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
11 #include <ddk/winddi.h>
12 #include <ddk/ntddk.h>
13 #include <ntos/minmax.h>
17 #include <include/mouse.h>
18 #include <include/object.h>
19 #include <include/dib.h>
20 #include <include/surface.h>
21 #include <include/copybits.h>
23 BOOL
EngIntersectRect(PRECTL prcDst
, PRECTL prcSrc1
, PRECTL prcSrc2
)
25 static const RECTL rclEmpty
= { 0, 0, 0, 0 };
27 prcDst
->left
= max(prcSrc1
->left
, prcSrc2
->left
);
28 prcDst
->right
= min(prcSrc1
->right
, prcSrc2
->right
);
30 if (prcDst
->left
< prcDst
->right
)
32 prcDst
->top
= max(prcSrc1
->top
, prcSrc2
->top
);
33 prcDst
->bottom
= min(prcSrc1
->bottom
, prcSrc2
->bottom
);
35 if (prcDst
->top
< prcDst
->bottom
) return(TRUE
);
46 EngBitBlt(SURFOBJ
*Dest
,
50 XLATEOBJ
*ColorTranslation
,
64 PSURFGDI DestGDI
, SourceGDI
;
66 PSURFOBJ TempSurf
= NULL
;
72 if(Source
!= NULL
) SourceGDI
= (PSURFGDI
)AccessInternalObjectFromUserObject(Source
);
73 if(Dest
!= NULL
) DestGDI
= (PSURFGDI
)AccessInternalObjectFromUserObject(Dest
);
75 MouseSafetyOnDrawStart(Source
, SourceGDI
, SourcePoint
->x
, SourcePoint
->y
,
76 (SourcePoint
->x
+ abs(DestRect
->right
- DestRect
->left
)),
77 (SourcePoint
->y
+ abs(DestRect
->bottom
- DestRect
->top
)));
78 MouseSafetyOnDrawStart(Dest
, DestGDI
, DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
80 // If we don't have to do anything special, we can punt to DrvCopyBits
82 if( (Mask
== NULL
) && (MaskRect
== NULL
) && (Brush
== NULL
) &&
83 (BrushOrigin
== NULL
) && (rop4
== 0) )
89 // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
90 // * The destination bitmap is not managed by the GDI OR
91 if(Dest
->iType
!= STYPE_BITMAP
)
93 // Destination surface is device managed
94 if (DestGDI
->BitBlt
!=NULL
)
98 // Get the source into a format compatible surface
103 TempRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
104 TempRect
.right
= DestRect
->right
- DestRect
->left
;
105 TempSize
.cx
= TempRect
.right
;
106 TempSize
.cy
= TempRect
.bottom
;
108 hTemp
= EngCreateBitmap(TempSize
,
109 DIB_GetDIBWidthBytes(DestRect
->right
- DestRect
->left
, BitsPerFormat(Dest
->iBitmapFormat
)),
110 Dest
->iBitmapFormat
, 0, NULL
);
111 TempSurf
= (PSURFOBJ
)AccessUserObject((ULONG
)hTemp
);
113 // FIXME: Skip creating a TempSurf if we have the same BPP and palette
114 EngBitBlt(TempSurf
, Source
, NULL
, NULL
, ColorTranslation
, &TempRect
, SourcePoint
, NULL
, NULL
, NULL
, 0);
117 ret
= DestGDI
->BitBlt(Dest
, TempSurf
, Mask
, ClipRegion
,
118 NULL
, DestRect
, &TempPoint
,
119 MaskRect
, Brush
, BrushOrigin
, rop4
);
121 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
122 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
128 // * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
129 if(Source
->iType
!= STYPE_BITMAP
&& SourceGDI
->CopyBits
== NULL
)
131 if (SourceGDI
->BitBlt
!=NULL
)
133 // Request the device driver to return the bitmap in a format compatible with the device
134 ret
= SourceGDI
->BitBlt(Dest
, Source
, Mask
, ClipRegion
,
135 NULL
, DestRect
, SourcePoint
,
136 MaskRect
, Brush
, BrushOrigin
, rop4
);
138 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
139 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
143 // Convert the surface from the driver into the required destination surface
147 // Determine clipping type
148 if (ClipRegion
== (CLIPOBJ
*) NULL
)
150 clippingType
= DC_TRIVIAL
;
152 clippingType
= ClipRegion
->iDComplexity
;
155 // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
159 CopyBitsCopy(Dest
, Source
, DestGDI
, SourceGDI
, DestRect
, SourcePoint
, Source
->lDelta
, ColorTranslation
);
161 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
162 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
168 // Clip the blt to the clip rectangle
169 EngIntersectRect(&rclTmp
, DestRect
, &ClipRegion
->rclBounds
);
171 ptlTmp
.x
= SourcePoint
->x
+ rclTmp
.left
- DestRect
->left
;
172 ptlTmp
.y
= SourcePoint
->y
+ rclTmp
.top
- DestRect
->top
;
174 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
175 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
181 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, CD_ANY
, ENUM_RECT_LIMIT
);
184 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
188 RECTL
* prclEnd
= &RectEnum
.arcl
[RectEnum
.c
];
189 RECTL
* prcl
= &RectEnum
.arcl
[0];
192 EngIntersectRect(prcl
, prcl
, DestRect
);
194 ptlTmp
.x
= SourcePoint
->x
+ prcl
->left
- DestRect
->left
;
195 ptlTmp
.y
= SourcePoint
->y
+ prcl
->top
- DestRect
->top
;
199 } while (prcl
< prclEnd
);
204 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
205 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
210 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
211 MouseSafetyOnDrawEnd(Dest
, DestGDI
);