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
);
77 MouseSafetyOnDrawStart(Source
, SourceGDI
, SourcePoint
->x
, SourcePoint
->y
,
78 (SourcePoint
->x
+ abs(DestRect
->right
- DestRect
->left
)),
79 (SourcePoint
->y
+ abs(DestRect
->bottom
- DestRect
->top
)));
81 MouseSafetyOnDrawStart(Dest
, DestGDI
, DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
83 // If we don't have to do anything special, we can punt to DrvCopyBits
85 if( (Mask
== NULL
) && (MaskRect
== NULL
) && (Brush
== NULL
) &&
86 (BrushOrigin
== NULL
) && (rop4
== 0) )
92 // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
93 // * The destination bitmap is not managed by the GDI OR
94 if(Dest
->iType
!= STYPE_BITMAP
)
96 // Destination surface is device managed
97 if (DestGDI
->BitBlt
!=NULL
)
101 // Get the source into a format compatible surface
106 TempRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
107 TempRect
.right
= DestRect
->right
- DestRect
->left
;
108 TempSize
.cx
= TempRect
.right
;
109 TempSize
.cy
= TempRect
.bottom
;
111 hTemp
= EngCreateBitmap(TempSize
,
112 DIB_GetDIBWidthBytes(DestRect
->right
- DestRect
->left
, BitsPerFormat(Dest
->iBitmapFormat
)),
113 Dest
->iBitmapFormat
, 0, NULL
);
114 TempSurf
= (PSURFOBJ
)AccessUserObject((ULONG
)hTemp
);
116 // FIXME: Skip creating a TempSurf if we have the same BPP and palette
117 EngBitBlt(TempSurf
, Source
, NULL
, NULL
, ColorTranslation
, &TempRect
, SourcePoint
, NULL
, NULL
, NULL
, 0);
120 ret
= DestGDI
->BitBlt(Dest
, TempSurf
, Mask
, ClipRegion
,
121 NULL
, DestRect
, &TempPoint
,
122 MaskRect
, Brush
, BrushOrigin
, rop4
);
124 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
125 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
131 // * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
132 if(Source
->iType
!= STYPE_BITMAP
&& SourceGDI
->CopyBits
== NULL
)
134 if (SourceGDI
->BitBlt
!=NULL
)
136 // Request the device driver to return the bitmap in a format compatible with the device
137 ret
= SourceGDI
->BitBlt(Dest
, Source
, Mask
, ClipRegion
,
138 NULL
, DestRect
, SourcePoint
,
139 MaskRect
, Brush
, BrushOrigin
, rop4
);
141 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
142 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
146 // Convert the surface from the driver into the required destination surface
150 // Determine clipping type
151 if (ClipRegion
== (CLIPOBJ
*) NULL
)
153 clippingType
= DC_TRIVIAL
;
155 clippingType
= ClipRegion
->iDComplexity
;
158 // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
162 CopyBitsCopy(Dest
, Source
, DestGDI
, SourceGDI
, DestRect
, SourcePoint
, Source
->lDelta
, ColorTranslation
);
164 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
165 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
171 // Clip the blt to the clip rectangle
172 EngIntersectRect(&rclTmp
, DestRect
, &ClipRegion
->rclBounds
);
174 ptlTmp
.x
= SourcePoint
->x
+ rclTmp
.left
- DestRect
->left
;
175 ptlTmp
.y
= SourcePoint
->y
+ rclTmp
.top
- DestRect
->top
;
177 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
178 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
184 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, CD_ANY
, ENUM_RECT_LIMIT
);
187 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
191 RECTL
* prclEnd
= &RectEnum
.arcl
[RectEnum
.c
];
192 RECTL
* prcl
= &RectEnum
.arcl
[0];
195 EngIntersectRect(prcl
, prcl
, DestRect
);
197 ptlTmp
.x
= SourcePoint
->x
+ prcl
->left
- DestRect
->left
;
198 ptlTmp
.y
= SourcePoint
->y
+ prcl
->top
- DestRect
->top
;
202 } while (prcl
< prclEnd
);
207 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
208 MouseSafetyOnDrawEnd(Dest
, DestGDI
);
213 MouseSafetyOnDrawEnd(Source
, SourceGDI
);
214 MouseSafetyOnDrawEnd(Dest
, DestGDI
);