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
35 typedef BOOLEAN (STDCALL
*PBLTRECTFUNC
)(SURFOBJ
* OutputObj
,
38 XLATEOBJ
* ColorTranslation
,
45 typedef BOOLEAN (STDCALL
*PSTRETCHRECTFUNC
)(SURFOBJ
* OutputObj
,
49 XLATEOBJ
* ColorTranslation
,
56 BOOL STDCALL
EngIntersectRect(RECTL
* prcDst
, RECTL
* prcSrc1
, RECTL
* prcSrc2
)
58 static const RECTL rclEmpty
= { 0, 0, 0, 0 };
60 prcDst
->left
= max(prcSrc1
->left
, prcSrc2
->left
);
61 prcDst
->right
= min(prcSrc1
->right
, prcSrc2
->right
);
63 if (prcDst
->left
< prcDst
->right
)
65 prcDst
->top
= max(prcSrc1
->top
, prcSrc2
->top
);
66 prcDst
->bottom
= min(prcSrc1
->bottom
, prcSrc2
->bottom
);
68 if (prcDst
->top
< prcDst
->bottom
)
79 static BOOLEAN STDCALL
80 BltMask(SURFOBJ
* Dest
,
83 XLATEOBJ
* ColorTranslation
,
91 LONG i
, j
, dx
, dy
, c8
;
93 static BYTE maskbit
[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
95 PGDIBRUSHINST GdiBrush
= NULL
;
96 SURFOBJ
*PatternObj
= NULL
;
97 PBITMAPOBJ PatternBitmap
;
98 ULONG PatternWidth
= 0, PatternHeight
= 0, PatternY
= 0;
105 dx
= DestRect
->right
- DestRect
->left
;
106 dy
= DestRect
->bottom
- DestRect
->top
;
108 if (Brush
->iSolidColor
== 0xFFFFFFFF)
110 GdiBrush
= CONTAINING_RECORD(
115 PatternBitmap
= BITMAPOBJ_LockBitmap(GdiBrush
->GdiBrushObject
->hbmPattern
);
116 if (PatternBitmap
!= NULL
)
118 PatternObj
= &PatternBitmap
->SurfObj
;
119 PatternWidth
= PatternObj
->sizlBitmap
.cx
;
120 PatternHeight
= PatternObj
->sizlBitmap
.cy
;
124 PatternBitmap
= NULL
;
126 tMask
= (PBYTE
)Mask
->pvScan0
+ SourcePoint
->y
* Mask
->lDelta
+ (SourcePoint
->x
>> 3);
127 for (j
= 0; j
< dy
; j
++)
130 c8
= SourcePoint
->x
& 0x07;
132 if (PatternBitmap
!= NULL
)
133 PatternY
= (DestRect
->top
+ j
) % PatternHeight
;
135 for (i
= 0; i
< dx
; i
++)
137 if (0 != (*lMask
& maskbit
[c8
]))
139 if (PatternBitmap
== NULL
)
141 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
142 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
, Brush
->iSolidColor
);
146 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
147 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
,
148 DIB_GetSource(PatternObj
, (DestRect
->left
+ i
) % PatternWidth
, PatternY
, GdiBrush
->XlateObject
));
158 tMask
+= Mask
->lDelta
;
161 if (PatternBitmap
!= NULL
)
162 BITMAPOBJ_UnlockBitmap(PatternBitmap
);
167 static BOOLEAN STDCALL
168 BltPatCopy(SURFOBJ
* Dest
,
171 XLATEOBJ
* ColorTranslation
,
179 // These functions are assigned if we're working with a DIB
180 // The assigned functions depend on the bitsPerPixel of the DIB
182 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_ColorFill(Dest
, DestRect
, Brush
->iSolidColor
);
187 static BOOLEAN STDCALL
188 CallDibBitBlt(SURFOBJ
* OutputObj
,
191 XLATEOBJ
* ColorTranslation
,
200 PGDIBRUSHINST GdiBrush
= NULL
;
201 BITMAPOBJ
*bmPattern
;
204 BltInfo
.DestSurface
= OutputObj
;
205 BltInfo
.SourceSurface
= InputObj
;
206 BltInfo
.PatternSurface
= NULL
;
207 BltInfo
.XlateSourceToDest
= ColorTranslation
;
208 BltInfo
.DestRect
= *OutputRect
;
209 BltInfo
.SourcePoint
= *InputPoint
;
211 if (ROP3_TO_ROP4(SRCCOPY
) == Rop4
)
212 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBltSrcCopy(&BltInfo
);
214 BltInfo
.XlatePatternToDest
= NULL
;
215 BltInfo
.Brush
= Brush
;
216 BltInfo
.BrushOrigin
= *BrushOrigin
;
220 if (ROP4_USES_PATTERN(Rop4
) && Brush
->iSolidColor
== 0xFFFFFFFF)
222 GdiBrush
= CONTAINING_RECORD(Brush
, GDIBRUSHINST
, BrushObject
);
223 if ((bmPattern
= BITMAPOBJ_LockBitmap(GdiBrush
->GdiBrushObject
->hbmPattern
)))
225 BltInfo
.PatternSurface
= &bmPattern
->SurfObj
;
229 /* FIXME - What to do here? */
231 BltInfo
.XlatePatternToDest
= GdiBrush
->XlateObject
;
238 Result
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_BitBlt(&BltInfo
);
241 if (bmPattern
!= NULL
)
243 BITMAPOBJ_UnlockBitmap(bmPattern
);
249 INT __cdecl
abs(INT nm
);
266 IN POINTL
*pptlBrush
,
276 ProbeForRead(prclTrg
, sizeof(RECTL
), 1);
277 RtlCopyMemory(&rclTrg
,prclTrg
, sizeof(RECTL
));
279 ProbeForRead(pptlSrc
, sizeof(POINTL
), 1);
280 RtlCopyMemory(&ptlSrc
, pptlSrc
, sizeof(POINTL
));
282 ProbeForRead(pptlMask
, sizeof(POINTL
), 1);
283 RtlCopyMemory(&ptlMask
, pptlMask
, sizeof(POINTL
));
285 ProbeForRead(pptlBrush
, sizeof(POINTL
), 1);
286 RtlCopyMemory(&ptlBrush
, pptlBrush
, sizeof(POINTL
));
291 _SEH_YIELD(return FALSE
);
295 return EngBitBlt(psoTrg
, psoSrc
, psoMask
, pco
, pxlo
, &rclTrg
, &ptlSrc
, &ptlMask
, pbo
, &ptlBrush
, rop4
);
302 EngBitBlt(SURFOBJ
*DestObj
,
306 XLATEOBJ
*ColorTranslation
,
322 INTENG_ENTER_LEAVE EnterLeaveSource
;
323 INTENG_ENTER_LEAVE EnterLeaveDest
;
326 PBLTRECTFUNC BltRectFunc
;
334 POINTL AdjustedBrushOrigin
;
336 UsesSource
= ROP4_USES_SOURCE(Rop4
);
337 UsesPattern
= ROP4_USES_PATTERN(Rop4
);
340 /* Copy destination onto itself: nop */
344 OutputRect
= *DestRect
;
345 if (OutputRect
.right
< OutputRect
.left
)
347 OutputRect
.left
= DestRect
->right
;
348 OutputRect
.right
= DestRect
->left
;
350 if (OutputRect
.bottom
< OutputRect
.top
)
352 OutputRect
.left
= DestRect
->right
;
353 OutputRect
.right
= DestRect
->left
;
358 if (NULL
== SourcePoint
)
363 /* Make sure we don't try to copy anything outside the valid source
365 InputPoint
= *SourcePoint
;
366 if (InputPoint
.x
< 0)
368 OutputRect
.left
-= InputPoint
.x
;
371 if (InputPoint
.y
< 0)
373 OutputRect
.top
-= InputPoint
.y
;
376 if (SourceObj
->sizlBitmap
.cx
< InputPoint
.x
+
377 OutputRect
.right
- OutputRect
.left
)
379 OutputRect
.right
= OutputRect
.left
+
380 SourceObj
->sizlBitmap
.cx
- InputPoint
.x
;
382 if (SourceObj
->sizlBitmap
.cy
< InputPoint
.y
+
383 OutputRect
.bottom
- OutputRect
.top
)
385 OutputRect
.bottom
= OutputRect
.top
+
386 SourceObj
->sizlBitmap
.cy
- InputPoint
.y
;
389 InputRect
.left
= InputPoint
.x
;
390 InputRect
.right
= InputPoint
.x
+ (OutputRect
.right
- OutputRect
.left
);
391 InputRect
.top
= InputPoint
.y
;
392 InputRect
.bottom
= InputPoint
.y
+ (OutputRect
.bottom
- OutputRect
.top
);
394 if (! IntEngEnter(&EnterLeaveSource
, SourceObj
, &InputRect
, TRUE
,
395 &Translate
, &InputObj
))
400 InputPoint
.x
+= Translate
.x
;
401 InputPoint
.y
+= Translate
.y
;
406 InputRect
.right
= DestRect
->right
- DestRect
->left
;
408 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
411 if (NULL
!= ClipRegion
)
413 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
415 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
416 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
417 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
419 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
421 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
422 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
424 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
426 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
427 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
428 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
430 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
432 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
433 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
437 /* Check for degenerate case: if height or width of OutputRect is 0 pixels
438 there's nothing to do */
439 if (OutputRect
.right
<= OutputRect
.left
||
440 OutputRect
.bottom
<= OutputRect
.top
)
444 IntEngLeave(&EnterLeaveSource
);
449 if (! IntEngEnter(&EnterLeaveDest
, DestObj
, &OutputRect
, FALSE
, &Translate
,
454 IntEngLeave(&EnterLeaveSource
);
459 OutputRect
.left
+= Translate
.x
;
460 OutputRect
.right
+= Translate
.x
;
461 OutputRect
.top
+= Translate
.y
;
462 OutputRect
.bottom
+= Translate
.y
;
466 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
467 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
471 AdjustedBrushOrigin
= Translate
;
474 /* Determine clipping type */
475 if (ClipRegion
== (CLIPOBJ
*) NULL
)
477 clippingType
= DC_TRIVIAL
;
481 clippingType
= ClipRegion
->iDComplexity
;
486 BltRectFunc
= BltMask
;
488 else if (ROP3_TO_ROP4(PATCOPY
) == Rop4
)
490 if (Brush
->iSolidColor
== 0xFFFFFFFF)
491 BltRectFunc
= CallDibBitBlt
;
493 BltRectFunc
= BltPatCopy
;
497 BltRectFunc
= CallDibBitBlt
;
501 switch (clippingType
)
504 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
505 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
,
506 &AdjustedBrushOrigin
, Rop4
);
509 /* Clip the blt to the clip rectangle */
510 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
511 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
512 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
513 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
514 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
516 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
517 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
518 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ColorTranslation
,
519 &CombinedRect
, &Pt
, MaskOrigin
, Brush
,
520 &AdjustedBrushOrigin
, Rop4
);
525 if (OutputObj
== InputObj
)
527 if (OutputRect
.top
< InputPoint
.y
)
529 Direction
= OutputRect
.left
< InputPoint
.x
?
530 CD_RIGHTDOWN
: CD_LEFTDOWN
;
534 Direction
= OutputRect
.left
< InputPoint
.x
?
535 CD_RIGHTUP
: CD_LEFTUP
;
542 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
545 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
548 for (i
= 0; i
< RectEnum
.c
; i
++)
550 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
551 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
552 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
553 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
554 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
556 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
557 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
558 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
,
559 ColorTranslation
, &CombinedRect
, &Pt
,
560 MaskOrigin
, Brush
, &AdjustedBrushOrigin
,
570 IntEngLeave(&EnterLeaveDest
);
573 IntEngLeave(&EnterLeaveSource
);
580 IntEngBitBltEx(SURFOBJ
*DestSurf
,
584 XLATEOBJ
*ColorTranslation
,
594 RECTL InputClippedRect
;
599 BITMAPOBJ
*SourceObj
= NULL
;
601 if (DestSurf
== NULL
)
605 DestObj
= CONTAINING_RECORD(DestSurf
, BITMAPOBJ
, SurfObj
);
608 InputClippedRect
= *DestRect
;
609 if (InputClippedRect
.right
< InputClippedRect
.left
)
611 InputClippedRect
.left
= DestRect
->right
;
612 InputClippedRect
.right
= DestRect
->left
;
614 if (InputClippedRect
.bottom
< InputClippedRect
.top
)
616 InputClippedRect
.top
= DestRect
->bottom
;
617 InputClippedRect
.bottom
= DestRect
->top
;
619 UsesSource
= ROP4_USES_SOURCE(Rop4
);
622 if (NULL
== SourcePoint
|| NULL
== SourceSurf
)
626 InputPoint
= *SourcePoint
;
628 /* Make sure we don't try to copy anything outside the valid source
630 if (InputPoint
.x
< 0)
632 InputClippedRect
.left
-= InputPoint
.x
;
635 if (InputPoint
.y
< 0)
637 InputClippedRect
.top
-= InputPoint
.y
;
640 if (SourceSurf
->sizlBitmap
.cx
< InputPoint
.x
+
641 InputClippedRect
.right
-
642 InputClippedRect
.left
)
644 InputClippedRect
.right
= InputClippedRect
.left
+
645 SourceSurf
->sizlBitmap
.cx
- InputPoint
.x
;
647 if (SourceSurf
->sizlBitmap
.cy
< InputPoint
.y
+
648 InputClippedRect
.bottom
-
649 InputClippedRect
.top
)
651 InputClippedRect
.bottom
= InputClippedRect
.top
+
652 SourceSurf
->sizlBitmap
.cy
- InputPoint
.y
;
655 if (InputClippedRect
.right
< InputClippedRect
.left
||
656 InputClippedRect
.bottom
< InputClippedRect
.top
)
658 /* Everything clipped away, nothing to do */
663 /* Clip against the bounds of the clipping region so we won't try to write
664 * outside the surface */
665 if (NULL
!= ClipRegion
)
667 if (! EngIntersectRect(&OutputRect
, &InputClippedRect
,
668 &ClipRegion
->rclBounds
))
672 InputPoint
.x
+= OutputRect
.left
- InputClippedRect
.left
;
673 InputPoint
.y
+= OutputRect
.top
- InputClippedRect
.top
;
677 OutputRect
= InputClippedRect
;
682 BITMAPOBJ_LockBitmapBits(DestObj
);
686 if (SourceSurf
!= DestSurf
)
688 SourceObj
= CONTAINING_RECORD(SourceSurf
, BITMAPOBJ
, SurfObj
);
689 BITMAPOBJ_LockBitmapBits(SourceObj
);
691 MouseSafetyOnDrawStart(SourceSurf
, InputPoint
.x
, InputPoint
.y
,
692 (InputPoint
.x
+ abs(DestRect
->right
- DestRect
->left
)),
693 (InputPoint
.y
+ abs(DestRect
->bottom
- DestRect
->top
)));
695 MouseSafetyOnDrawStart(DestSurf
, OutputRect
.left
, OutputRect
.top
,
696 OutputRect
.right
, OutputRect
.bottom
);
702 /* Call the driver's DrvBitBlt if available */
703 if (DestObj
->flHooks
& HOOK_BITBLT
)
705 ret
= GDIDEVFUNCS(DestSurf
).BitBlt(
706 DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
707 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, BrushOrigin
,
713 ret
= EngBitBlt(DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
714 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, BrushOrigin
,
720 MouseSafetyOnDrawEnd(DestSurf
);
723 MouseSafetyOnDrawEnd(SourceSurf
);
724 if (SourceSurf
!= DestSurf
)
726 BITMAPOBJ_UnlockBitmapBits(SourceObj
);
730 BITMAPOBJ_UnlockBitmapBits(DestObj
);
736 static BOOLEAN STDCALL
737 CallDibStretchBlt(SURFOBJ
* OutputObj
,
741 XLATEOBJ
* ColorTranslation
,
748 POINTL RealBrushOrigin
;
749 if (BrushOrigin
== NULL
)
751 RealBrushOrigin
.x
= RealBrushOrigin
.y
= 0;
755 RealBrushOrigin
= *BrushOrigin
;
757 return DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_StretchBlt(
758 OutputObj
, InputObj
, OutputRect
, InputRect
, MaskOrigin
, RealBrushOrigin
, ClipRegion
, ColorTranslation
, Mode
);
766 IN SURFOBJ
*SourceObj
,
768 IN CLIPOBJ
*ClipRegion
,
769 IN XLATEOBJ
*ColorTranslation
,
770 IN COLORADJUSTMENT
*pca
,
771 IN POINTL
*BrushOrigin
,
774 IN POINTL
*MaskOrigin
,
786 ProbeForRead(pca
, sizeof(COLORADJUSTMENT
), 1);
787 RtlCopyMemory(&ca
,pca
, sizeof(COLORADJUSTMENT
));
789 ProbeForRead(BrushOrigin
, sizeof(POINTL
), 1);
790 RtlCopyMemory(&lBrushOrigin
, BrushOrigin
, sizeof(POINTL
));
792 ProbeForRead(prclDest
, sizeof(RECTL
), 1);
793 RtlCopyMemory(&rclDest
, prclDest
, sizeof(RECTL
));
795 ProbeForRead(prclSrc
, sizeof(RECTL
), 1);
796 RtlCopyMemory(&rclSrc
, prclSrc
, sizeof(RECTL
));
798 ProbeForRead(MaskOrigin
, sizeof(POINTL
), 1);
799 RtlCopyMemory(&lMaskOrigin
, MaskOrigin
, sizeof(POINTL
));
804 _SEH_YIELD(return FALSE
);
808 return EngStretchBlt(DestObj
, SourceObj
, Mask
, ClipRegion
, ColorTranslation
, &ca
, &lBrushOrigin
, &rclDest
, &rclSrc
, &lMaskOrigin
, Mode
);
815 IN SURFOBJ
*SourceObj
,
817 IN CLIPOBJ
*ClipRegion
,
818 IN XLATEOBJ
*ColorTranslation
,
819 IN COLORADJUSTMENT
*pca
,
820 IN POINTL
*BrushOrigin
,
823 IN POINTL
*MaskOrigin
,
827 // www.osr.com/ddk/graphics/gdifncs_0bs7.htm
833 INTENG_ENTER_LEAVE EnterLeaveSource
;
834 INTENG_ENTER_LEAVE EnterLeaveDest
;
837 PSTRETCHRECTFUNC BltRectFunc
;
839 POINTL AdjustedBrushOrigin
;
841 InputRect
.left
= prclSrc
->left
;
842 InputRect
.right
= prclSrc
->right
;
843 InputRect
.top
= prclSrc
->top
;
844 InputRect
.bottom
= prclSrc
->bottom
;
846 if (! IntEngEnter(&EnterLeaveSource
, SourceObj
, &InputRect
, TRUE
, &Translate
, &InputObj
))
851 InputPoint
.x
= InputRect
.left
+ Translate
.x
;
852 InputPoint
.y
= InputRect
.top
+ Translate
.y
;
854 OutputRect
= *prclDest
;
856 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
858 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
860 IntEngLeave(&EnterLeaveSource
);
864 if (! IntEngEnter(&EnterLeaveDest
, DestObj
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
866 IntEngLeave(&EnterLeaveSource
);
870 OutputRect
.left
= prclDest
->left
+ Translate
.x
;
871 OutputRect
.right
= prclDest
->right
+ Translate
.x
;
872 OutputRect
.top
= prclDest
->top
+ Translate
.y
;
873 OutputRect
.bottom
= prclDest
->bottom
+ Translate
.y
;
875 if (NULL
!= BrushOrigin
)
877 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
878 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
882 AdjustedBrushOrigin
= Translate
;
887 //BltRectFunc = BltMask;
888 DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
889 IntEngLeave(&EnterLeaveDest
);
890 IntEngLeave(&EnterLeaveSource
);
896 BltRectFunc
= CallDibStretchBlt
;
900 Ret
= (*BltRectFunc
)(OutputObj
, InputObj
, Mask
, ClipRegion
,
901 ColorTranslation
, &OutputRect
, &InputRect
, MaskOrigin
,
902 &AdjustedBrushOrigin
, Mode
);
904 IntEngLeave(&EnterLeaveDest
);
905 IntEngLeave(&EnterLeaveSource
);
911 IntEngStretchBlt(SURFOBJ
*DestSurf
,
915 XLATEOBJ
*ColorTranslation
,
927 BITMAPOBJ
*SourceObj
= NULL
;
930 DestObj
= CONTAINING_RECORD(DestSurf
, BITMAPOBJ
, SurfObj
);
933 if (pMaskOrigin
!= NULL
)
935 MaskOrigin
.x
= pMaskOrigin
->x
; MaskOrigin
.y
= pMaskOrigin
->y
;
941 BITMAPOBJ_LockBitmapBits(DestObj
);
942 MouseSafetyOnDrawStart(DestSurf
, DestRect
->left
, DestRect
->top
,
943 DestRect
->right
, DestRect
->bottom
);
945 if (NULL
!= SourceSurf
)
947 SourceObj
= CONTAINING_RECORD(SourceSurf
, BITMAPOBJ
, SurfObj
);
949 if (SourceSurf
!= DestSurf
)
951 BITMAPOBJ_LockBitmapBits(SourceObj
);
953 MouseSafetyOnDrawStart(SourceSurf
, SourceRect
->left
, SourceRect
->top
,
954 SourceRect
->right
, SourceRect
->bottom
);
957 /* Prepare color adjustment */
959 /* Call the driver's DrvStretchBlt if available */
960 if (DestObj
->flHooks
& HOOK_STRETCHBLT
)
962 /* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
963 SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
964 // FIXME: MaskOrigin is always NULL !
965 ret
= GDIDEVFUNCS(DestSurf
).StretchBlt(
966 DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
967 &ca
, BrushOrigin
, DestRect
, SourceRect
, NULL
, Mode
);
972 // FIXME: see previous fixme
973 ret
= EngStretchBlt(DestSurf
, SourceSurf
, MaskSurf
, ClipRegion
, ColorTranslation
,
974 &ca
, BrushOrigin
, DestRect
, SourceRect
, NULL
, Mode
);
977 if (NULL
!= SourceSurf
)
979 MouseSafetyOnDrawEnd(SourceSurf
);
980 if (SourceSurf
!= DestSurf
)
982 BITMAPOBJ_UnlockBitmapBits(SourceObj
);
985 MouseSafetyOnDrawEnd(DestSurf
);
986 BITMAPOBJ_UnlockBitmapBits(DestObj
);
997 NtGdiEngAlphaBlend(IN SURFOBJ
*Dest
,
999 IN CLIPOBJ
*ClipRegion
,
1000 IN XLATEOBJ
*ColorTranslation
,
1001 IN PRECTL upDestRect
,
1002 IN PRECTL upSourceRect
,
1003 IN BLENDOBJ
*BlendObj
)
1010 ProbeForRead(upDestRect
, sizeof(RECTL
), 1);
1011 RtlCopyMemory(&DestRect
,upDestRect
, sizeof(RECTL
));
1013 ProbeForRead(upSourceRect
, sizeof(RECTL
), 1);
1014 RtlCopyMemory(&SourceRect
, upSourceRect
, sizeof(RECTL
));
1019 _SEH_YIELD(return FALSE
);
1023 return EngAlphaBlend(Dest
, Source
, ClipRegion
, ColorTranslation
, &DestRect
, &SourceRect
, BlendObj
);
1031 EngAlphaBlend(IN SURFOBJ
*Dest
,
1033 IN CLIPOBJ
*ClipRegion
,
1034 IN XLATEOBJ
*ColorTranslation
,
1036 IN PRECTL SourceRect
,
1037 IN BLENDOBJ
*BlendObj
)
1039 RECTL SourceStretchedRect
;
1040 SIZEL SourceStretchedSize
;
1041 HBITMAP SourceStretchedBitmap
= 0;
1042 SURFOBJ
* SourceStretchedObj
= NULL
;
1049 INTENG_ENTER_LEAVE EnterLeaveSource
;
1050 INTENG_ENTER_LEAVE EnterLeaveDest
;
1060 DPRINT("EngAlphaBlend(Dest:0x%p, Source:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", Dest
, Source
, ClipRegion
, ColorTranslation
);
1061 DPRINT(" DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
1062 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
,
1063 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
);
1064 DPRINT(" BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj
->BlendFunction
.BlendOp
,
1065 BlendObj
->BlendFunction
.BlendFlags
, BlendObj
->BlendFunction
.SourceConstantAlpha
,
1066 BlendObj
->BlendFunction
.AlphaFormat
);
1068 /* Validate input */
1069 if (DestRect
->left
>= DestRect
->right
|| DestRect
->top
>= DestRect
->bottom
)
1071 DPRINT1("Empty destination rectangle!\n");
1074 if (SourceRect
->left
>= SourceRect
->right
|| SourceRect
->top
>= SourceRect
->bottom
)
1076 DPRINT1("Empty source rectangle!\n");
1079 if (Dest
== Source
&&
1080 !(DestRect
->left
>= SourceRect
->right
|| SourceRect
->left
>= DestRect
->right
||
1081 DestRect
->top
>= SourceRect
->bottom
|| SourceRect
->top
>= DestRect
->bottom
))
1083 DPRINT1("Source and destination rectangles overlap!\n");
1087 if (BlendObj
->BlendFunction
.BlendOp
!= AC_SRC_OVER
)
1089 DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj
->BlendFunction
.BlendOp
);
1092 if (BlendObj
->BlendFunction
.BlendFlags
!= 0)
1094 DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj
->BlendFunction
.BlendFlags
);
1097 if ((BlendObj
->BlendFunction
.AlphaFormat
& ~AC_SRC_ALPHA
) != 0)
1099 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj
->BlendFunction
.AlphaFormat
);
1103 /* Check if there is anything to draw */
1104 if (ClipRegion
!= NULL
&&
1105 (ClipRegion
->rclBounds
.left
>= ClipRegion
->rclBounds
.right
||
1106 ClipRegion
->rclBounds
.top
>= ClipRegion
->rclBounds
.bottom
))
1112 /* Stretch source if needed */
1113 if (DestRect
->right
- DestRect
->left
!= SourceRect
->right
- SourceRect
->left
||
1114 DestRect
->bottom
- DestRect
->top
!= SourceRect
->bottom
- SourceRect
->top
)
1116 SourceStretchedSize
.cx
= DestRect
->right
- DestRect
->left
;
1117 SourceStretchedSize
.cy
= DestRect
->bottom
- DestRect
->top
;
1118 Width
= DIB_GetDIBWidthBytes(SourceStretchedSize
.cx
, BitsPerFormat(Source
->iBitmapFormat
));
1119 /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt
1120 if possible to get a HW accelerated stretch. */
1121 SourceStretchedBitmap
= EngCreateBitmap(SourceStretchedSize
, Width
, Source
->iBitmapFormat
,
1122 BMF_TOPDOWN
| BMF_NOZEROINIT
, NULL
);
1123 if (SourceStretchedBitmap
== 0)
1125 DPRINT1("EngCreateBitmap failed!\n");
1128 SourceStretchedObj
= EngLockSurface((HSURF
)SourceStretchedBitmap
);
1129 if (SourceStretchedObj
== NULL
)
1131 DPRINT1("EngLockSurface failed!\n");
1132 EngDeleteSurface((HSURF
)SourceStretchedBitmap
);
1136 SourceStretchedRect
.left
= 0;
1137 SourceStretchedRect
.right
= SourceStretchedSize
.cx
;
1138 SourceStretchedRect
.top
= 0;
1139 SourceStretchedRect
.bottom
= SourceStretchedSize
.cy
;
1140 /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
1141 try to acquire an already acquired mutex (lock the already locked source surface) */
1142 /*if (!IntEngStretchBlt(SourceStretchedObj, Source, NULL, NULL,
1143 NULL, &SourceStretchedRect, SourceRect, NULL,
1144 NULL, NULL, COLORONCOLOR))*/
1145 if (!EngStretchBlt(SourceStretchedObj
, Source
, NULL
, NULL
, NULL
,
1146 NULL
, NULL
, &SourceStretchedRect
, SourceRect
,
1147 NULL
, COLORONCOLOR
))
1149 DPRINT1("EngStretchBlt failed!\n");
1150 EngFreeMem(SourceStretchedObj
->pvBits
);
1151 EngUnlockSurface(SourceStretchedObj
);
1152 EngDeleteSurface((HSURF
)SourceStretchedBitmap
);
1155 SourceRect
= &SourceStretchedRect
;
1156 Source
= SourceStretchedObj
;
1159 /* Now call the DIB function */
1160 InputRect
.left
= SourceRect
->left
;
1161 InputRect
.right
= SourceRect
->right
;
1162 InputRect
.top
= SourceRect
->top
;
1163 InputRect
.bottom
= SourceRect
->bottom
;
1164 if (!IntEngEnter(&EnterLeaveSource
, Source
, &InputRect
, TRUE
, &Translate
, &InputObj
))
1166 if (SourceStretchedObj
!= NULL
)
1168 EngFreeMem(SourceStretchedObj
->pvBits
);
1169 EngUnlockSurface(SourceStretchedObj
);
1171 if (SourceStretchedBitmap
!= 0)
1173 EngDeleteSurface((HSURF
)SourceStretchedBitmap
);
1177 InputRect
.left
= SourceRect
->left
+ Translate
.x
;
1178 InputRect
.right
= SourceRect
->right
+ Translate
.x
;
1179 InputRect
.top
= SourceRect
->top
+ Translate
.y
;
1180 InputRect
.bottom
= SourceRect
->bottom
+ Translate
.y
;
1182 OutputRect
.left
= DestRect
->left
;
1183 OutputRect
.right
= DestRect
->right
;
1184 OutputRect
.top
= DestRect
->top
;
1185 OutputRect
.bottom
= DestRect
->bottom
;
1186 if (!IntEngEnter(&EnterLeaveDest
, Dest
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
1188 IntEngLeave(&EnterLeaveSource
);
1189 if (SourceStretchedObj
!= NULL
)
1191 EngFreeMem(SourceStretchedObj
->pvBits
);
1192 EngUnlockSurface(SourceStretchedObj
);
1194 if (SourceStretchedBitmap
!= 0)
1196 EngDeleteSurface((HSURF
)SourceStretchedBitmap
);
1200 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
1201 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
1202 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
1203 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
1206 ClippingType
= (ClipRegion
== NULL
) ? DC_TRIVIAL
: ClipRegion
->iDComplexity
;
1207 switch (ClippingType
)
1210 Ret
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_AlphaBlend(
1211 OutputObj
, InputObj
, &OutputRect
, &InputRect
, ClipRegion
, ColorTranslation
, BlendObj
);
1215 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
1216 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
1217 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
1218 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
1219 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
1221 Rect
.left
= InputRect
.left
+ CombinedRect
.left
- OutputRect
.left
;
1222 Rect
.right
= InputRect
.right
+ CombinedRect
.right
- OutputRect
.right
;
1223 Rect
.top
= InputRect
.top
+ CombinedRect
.top
- OutputRect
.top
;
1224 Rect
.bottom
= InputRect
.bottom
+ CombinedRect
.bottom
- OutputRect
.bottom
;
1225 Ret
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_AlphaBlend(
1226 OutputObj
, InputObj
, &CombinedRect
, &Rect
, ClipRegion
, ColorTranslation
, BlendObj
);
1232 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, CD_ANY
, 0);
1235 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
1238 for (i
= 0; i
< RectEnum
.c
; i
++)
1240 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
1241 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
1242 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
1243 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
1244 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
1246 Rect
.left
= InputRect
.left
+ CombinedRect
.left
- OutputRect
.left
;
1247 Rect
.right
= InputRect
.right
+ CombinedRect
.right
- OutputRect
.right
;
1248 Rect
.top
= InputRect
.top
+ CombinedRect
.top
- OutputRect
.top
;
1249 Rect
.bottom
= InputRect
.bottom
+ CombinedRect
.bottom
- OutputRect
.bottom
;
1250 Ret
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_AlphaBlend(
1251 OutputObj
, InputObj
, &CombinedRect
, &Rect
, ClipRegion
, ColorTranslation
, BlendObj
) && Ret
;
1264 IntEngLeave(&EnterLeaveDest
);
1265 IntEngLeave(&EnterLeaveSource
);
1267 if (SourceStretchedObj
!= NULL
)
1269 EngFreeMem(SourceStretchedObj
->pvBits
);
1270 EngUnlockSurface(SourceStretchedObj
);
1272 if (SourceStretchedBitmap
!= 0)
1274 EngDeleteSurface((HSURF
)SourceStretchedBitmap
);
1281 IntEngAlphaBlend(IN SURFOBJ
*Dest
,
1283 IN CLIPOBJ
*ClipRegion
,
1284 IN XLATEOBJ
*ColorTranslation
,
1286 IN PRECTL SourceRect
,
1287 IN BLENDOBJ
*BlendObj
)
1291 BITMAPOBJ
*SourceObj
;
1294 DestObj
= CONTAINING_RECORD(Dest
, BITMAPOBJ
, SurfObj
);
1298 SourceObj
= CONTAINING_RECORD(Source
, BITMAPOBJ
, SurfObj
);
1304 /* Check if there is anything to draw */
1305 if (ClipRegion
!= NULL
&&
1306 (ClipRegion
->rclBounds
.left
>= ClipRegion
->rclBounds
.right
||
1307 ClipRegion
->rclBounds
.top
>= ClipRegion
->rclBounds
.bottom
))
1313 BITMAPOBJ_LockBitmapBits(DestObj
);
1314 MouseSafetyOnDrawStart(Dest
, DestRect
->left
, DestRect
->top
,
1315 DestRect
->right
, DestRect
->bottom
);
1318 BITMAPOBJ_LockBitmapBits(SourceObj
);
1319 MouseSafetyOnDrawStart(Source
, SourceRect
->left
, SourceRect
->top
,
1320 SourceRect
->right
, SourceRect
->bottom
);
1322 /* Call the driver's DrvAlphaBlend if available */
1323 if (DestObj
->flHooks
& HOOK_ALPHABLEND
)
1325 ret
= GDIDEVFUNCS(Dest
).AlphaBlend(
1326 Dest
, Source
, ClipRegion
, ColorTranslation
,
1327 DestRect
, SourceRect
, BlendObj
);
1332 ret
= EngAlphaBlend(Dest
, Source
, ClipRegion
, ColorTranslation
,
1333 DestRect
, SourceRect
, BlendObj
);
1336 MouseSafetyOnDrawEnd(Source
);
1338 BITMAPOBJ_UnlockBitmapBits(SourceObj
);
1339 MouseSafetyOnDrawEnd(Dest
);
1340 BITMAPOBJ_UnlockBitmapBits(DestObj
);
1345 /**** REACTOS FONT RENDERING CODE *********************************************/
1347 /* renders the alpha mask bitmap */
1348 static BOOLEAN STDCALL
1349 AlphaBltMask(SURFOBJ
* Dest
,
1352 XLATEOBJ
* ColorTranslation
,
1353 XLATEOBJ
* SrcColorTranslation
,
1355 POINTL
* SourcePoint
,
1362 ULONG Background
, BrushColor
, NewColor
;
1363 BYTE
*tMask
, *lMask
;
1365 dx
= DestRect
->right
- DestRect
->left
;
1366 dy
= DestRect
->bottom
- DestRect
->top
;
1370 BrushColor
= XLATEOBJ_iXlate(SrcColorTranslation
, Brush
->iSolidColor
);
1371 r
= (int)GetRValue(BrushColor
);
1372 g
= (int)GetGValue(BrushColor
);
1373 b
= (int)GetBValue(BrushColor
);
1375 tMask
= (PBYTE
)Mask
->pvScan0
+ (SourcePoint
->y
* Mask
->lDelta
) + SourcePoint
->x
;
1376 for (j
= 0; j
< dy
; j
++)
1379 for (i
= 0; i
< dx
; i
++)
1385 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
1386 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
, Brush
->iSolidColor
);
1390 Background
= DIB_GetSource(Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
,
1391 SrcColorTranslation
);
1394 RGB((*lMask
* (r
- GetRValue(Background
)) >> 8) + GetRValue(Background
),
1395 (*lMask
* (g
- GetGValue(Background
)) >> 8) + GetGValue(Background
),
1396 (*lMask
* (b
- GetBValue(Background
)) >> 8) + GetBValue(Background
));
1398 Background
= XLATEOBJ_iXlate(ColorTranslation
, NewColor
);
1399 DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_PutPixel(
1400 Dest
, DestRect
->left
+ i
, DestRect
->top
+ j
, Background
);
1405 tMask
+= Mask
->lDelta
;
1416 EngMaskBitBlt(SURFOBJ
*DestObj
,
1418 CLIPOBJ
*ClipRegion
,
1419 XLATEOBJ
*DestColorTranslation
,
1420 XLATEOBJ
*SourceColorTranslation
,
1422 POINTL
*SourcePoint
,
1425 POINTL
*BrushOrigin
)
1435 INTENG_ENTER_LEAVE EnterLeaveSource
;
1436 INTENG_ENTER_LEAVE EnterLeaveDest
;
1444 POINTL AdjustedBrushOrigin
;
1448 if (NULL
!= SourcePoint
)
1450 InputRect
.left
= SourcePoint
->x
;
1451 InputRect
.right
= SourcePoint
->x
+ (DestRect
->right
- DestRect
->left
);
1452 InputRect
.top
= SourcePoint
->y
;
1453 InputRect
.bottom
= SourcePoint
->y
+ (DestRect
->bottom
- DestRect
->top
);
1458 InputRect
.right
= DestRect
->right
- DestRect
->left
;
1460 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
1463 if (! IntEngEnter(&EnterLeaveSource
, DestObj
, &InputRect
, TRUE
, &Translate
, &InputObj
))
1468 if (NULL
!= SourcePoint
)
1470 InputPoint
.x
= SourcePoint
->x
+ Translate
.x
;
1471 InputPoint
.y
= SourcePoint
->y
+ Translate
.y
;
1479 OutputRect
= *DestRect
;
1480 if (NULL
!= ClipRegion
)
1482 if (OutputRect
.left
< ClipRegion
->rclBounds
.left
)
1484 InputRect
.left
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
1485 InputPoint
.x
+= ClipRegion
->rclBounds
.left
- OutputRect
.left
;
1486 OutputRect
.left
= ClipRegion
->rclBounds
.left
;
1488 if (ClipRegion
->rclBounds
.right
< OutputRect
.right
)
1490 InputRect
.right
-= OutputRect
.right
- ClipRegion
->rclBounds
.right
;
1491 OutputRect
.right
= ClipRegion
->rclBounds
.right
;
1493 if (OutputRect
.top
< ClipRegion
->rclBounds
.top
)
1495 InputRect
.top
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
1496 InputPoint
.y
+= ClipRegion
->rclBounds
.top
- OutputRect
.top
;
1497 OutputRect
.top
= ClipRegion
->rclBounds
.top
;
1499 if (ClipRegion
->rclBounds
.bottom
< OutputRect
.bottom
)
1501 InputRect
.bottom
-= OutputRect
.bottom
- ClipRegion
->rclBounds
.bottom
;
1502 OutputRect
.bottom
= ClipRegion
->rclBounds
.bottom
;
1506 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
1508 if (OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
1510 IntEngLeave(&EnterLeaveSource
);
1514 if (! IntEngEnter(&EnterLeaveDest
, DestObj
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
1516 IntEngLeave(&EnterLeaveSource
);
1520 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
1521 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
1522 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
1523 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
1527 AdjustedBrushOrigin
.x
= BrushOrigin
->x
+ Translate
.x
;
1528 AdjustedBrushOrigin
.y
= BrushOrigin
->y
+ Translate
.y
;
1531 AdjustedBrushOrigin
= Translate
;
1533 // Determine clipping type
1534 if (ClipRegion
== (CLIPOBJ
*) NULL
)
1536 clippingType
= DC_TRIVIAL
;
1538 clippingType
= ClipRegion
->iDComplexity
;
1541 switch (clippingType
)
1544 if (Mask
->iBitmapFormat
== BMF_8BPP
)
1545 Ret
= AlphaBltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
, SourceColorTranslation
,
1546 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
);
1548 Ret
= BltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
,
1549 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
,
1553 // Clip the blt to the clip rectangle
1554 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
1555 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
1556 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
1557 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
1558 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
1560 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
1561 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
1562 if (Mask
->iBitmapFormat
== BMF_8BPP
)
1564 Ret
= AlphaBltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
, SourceColorTranslation
,
1565 &CombinedRect
, &Pt
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
);
1569 Ret
= BltMask(OutputObj
, InputObj
, Mask
, DestColorTranslation
,
1570 &CombinedRect
, &Pt
, MaskOrigin
, Brush
, &AdjustedBrushOrigin
, R4_MASK
);
1576 if (OutputObj
== InputObj
)
1578 if (OutputRect
.top
< InputPoint
.y
)
1580 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
1584 Direction
= OutputRect
.left
< InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
;
1591 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, Direction
, 0);
1594 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
1596 for (i
= 0; i
< RectEnum
.c
; i
++)
1598 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
1599 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
1600 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
1601 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
1602 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
1604 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
1605 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
1606 if (Mask
->iBitmapFormat
== BMF_8BPP
)
1608 Ret
= AlphaBltMask(OutputObj
, InputObj
, Mask
,
1609 DestColorTranslation
,
1610 SourceColorTranslation
,
1611 &CombinedRect
, &Pt
, MaskOrigin
, Brush
,
1612 &AdjustedBrushOrigin
) && Ret
;
1616 Ret
= BltMask(OutputObj
, InputObj
, Mask
,
1617 DestColorTranslation
, &CombinedRect
, &Pt
,
1618 MaskOrigin
, Brush
, &AdjustedBrushOrigin
,
1629 IntEngLeave(&EnterLeaveDest
);
1630 IntEngLeave(&EnterLeaveSource
);
1636 IntEngMaskBlt(SURFOBJ
*DestSurf
,
1638 CLIPOBJ
*ClipRegion
,
1639 XLATEOBJ
*DestColorTranslation
,
1640 XLATEOBJ
*SourceColorTranslation
,
1642 POINTL
*SourcePoint
,
1645 POINTL
*BrushOrigin
)
1654 if (NULL
!= SourcePoint
)
1656 InputPoint
= *SourcePoint
;
1659 /* Clip against the bounds of the clipping region so we won't try to write
1660 * outside the surface */
1661 if (NULL
!= ClipRegion
)
1663 if (! EngIntersectRect(&OutputRect
, DestRect
, &ClipRegion
->rclBounds
))
1667 InputPoint
.x
+= OutputRect
.left
- DestRect
->left
;
1668 InputPoint
.y
+= OutputRect
.top
- DestRect
->top
;
1672 OutputRect
= *DestRect
;
1675 /* No success yet */
1678 DestObj
= CONTAINING_RECORD(DestSurf
, BITMAPOBJ
, SurfObj
);
1680 BITMAPOBJ_LockBitmapBits(DestObj
);
1681 MouseSafetyOnDrawStart(DestSurf
, OutputRect
.left
, OutputRect
.top
,
1682 OutputRect
.right
, OutputRect
.bottom
);
1684 /* Dummy BitBlt to let driver know that it should flush its changes.
1685 This should really be done using a call to DrvSynchronizeSurface,
1686 but the VMware driver doesn't hook that call. */
1687 IntEngBitBltEx(DestSurf
, NULL
, Mask
, ClipRegion
, DestColorTranslation
,
1688 DestRect
, SourcePoint
, MaskOrigin
, Brush
, BrushOrigin
,
1691 ret
= EngMaskBitBlt(DestSurf
, Mask
, ClipRegion
, DestColorTranslation
, SourceColorTranslation
,
1692 &OutputRect
, &InputPoint
, MaskOrigin
, Brush
, BrushOrigin
);
1694 /* Dummy BitBlt to let driver know that something has changed. */
1695 IntEngBitBltEx(DestSurf
, NULL
, Mask
, ClipRegion
, DestColorTranslation
,
1696 DestRect
, SourcePoint
, MaskOrigin
, Brush
, BrushOrigin
,
1699 MouseSafetyOnDrawEnd(DestSurf
);
1700 BITMAPOBJ_UnlockBitmapBits(DestObj
);