ReactOS 0.4.15-dev-7924-g5949c20
copybits.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI EngCopyBits Function
5 * FILE: win32ss/gdi/eng/copybits.c
6 * PROGRAMERS: Jason Filby
7 * Doug Lyons
8 */
9
10#include <win32k.h>
11
12#define NDEBUG
13#include <debug.h>
14
15/*
16 * @implemented
17 */
20 _In_ SURFOBJ *psoDest,
21 _In_ SURFOBJ *psoSource,
22 _In_opt_ CLIPOBJ *Clip,
23 _In_opt_ XLATEOBJ *ColorTranslation,
24 _In_ RECTL *DestRect,
25 _In_ POINTL *SourcePoint)
26{
27 BOOL ret;
28 BYTE clippingType;
29 RECT_ENUM RectEnum;
30 BOOL EnumMore;
31 BLTINFO BltInfo;
32 SURFACE *psurfDest;
33 SURFACE *psurfSource;
34 RECTL rclDest = *DestRect;
35 POINTL ptlSrc = *SourcePoint;
36 LONG lTmp;
37 BOOL bTopToBottom;
38
39 DPRINT("Entering EngCopyBits with SourcePoint (%d,%d) and DestRect (%d,%d)-(%d,%d).\n",
40 SourcePoint->x, SourcePoint->y, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
41
42 DPRINT("psoSource cx/cy is %d/%d and psoDest cx/cy is %d/%d.\n",
43 psoSource->sizlBitmap.cx, psoSource->sizlBitmap.cy, psoDest->sizlBitmap.cx, psoDest->sizlBitmap.cy);
44
45 /* Retrieve Top Down/flip here and then make Well-Ordered again */
46 if (DestRect->top > DestRect->bottom)
47 {
48 bTopToBottom = TRUE;
49 lTmp = DestRect->top;
50 DestRect->top = DestRect->bottom;
51 DestRect->bottom = lTmp;
52 rclDest = *DestRect;
53 }
54 else
55 {
56 bTopToBottom = FALSE;
57 }
58
59 DPRINT("bTopToBottom is '%d'.\n", bTopToBottom);
60
61 ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL);
62
63 psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
64 psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
65
66 /* Clip dest rect against source surface size / source point */
67 if (psoSource->sizlBitmap.cx - ptlSrc.x < rclDest.right - rclDest.left)
68 rclDest.right = rclDest.left + psoSource->sizlBitmap.cx - ptlSrc.x;
69 if (psoSource->sizlBitmap.cy - ptlSrc.y < rclDest.bottom - rclDest.top)
70 rclDest.bottom = rclDest.top + psoSource->sizlBitmap.cy - ptlSrc.y;
71
72 /* Clip dest rect against target surface size */
73 if (rclDest.right > psoDest->sizlBitmap.cx)
74 rclDest.right = psoDest->sizlBitmap.cx;
75 if (rclDest.bottom > psoDest->sizlBitmap.cy)
76 rclDest.bottom = psoDest->sizlBitmap.cy;
77 if (RECTL_bIsEmptyRect(&rclDest)) return TRUE;
78 DestRect = &rclDest;
79
80 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
81 // mark the copy block function to be DrvCopyBits instead of the
82 // GDI's copy bit function so as to remove clipping from the
83 // driver's responsibility
84
85 // If one of the surfaces isn't managed by the GDI
86 if ((psoDest->iType!=STYPE_BITMAP) || (psoSource->iType!=STYPE_BITMAP))
87 {
88 // Destination surface is device managed
89 if (psoDest->iType!=STYPE_BITMAP)
90 {
91 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
92 if (psurfDest->flags & HOOK_COPYBITS)
93 {
94 ret = GDIDEVFUNCS(psoDest).CopyBits(
95 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
96
97 goto cleanup;
98 }
99 }
100
101 // Source surface is device managed
102 if (psoSource->iType!=STYPE_BITMAP)
103 {
104 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */
105 if (psurfSource->flags & HOOK_COPYBITS)
106 {
107 ret = GDIDEVFUNCS(psoSource).CopyBits(
108 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
109
110 goto cleanup;
111 }
112 }
113
114 // If CopyBits wasn't hooked, BitBlt must be
115 ret = IntEngBitBlt(psoDest, psoSource,
116 NULL, Clip, ColorTranslation, DestRect, SourcePoint,
118
119 goto cleanup;
120 }
121
122 // Determine clipping type
123 if (!Clip)
124 {
125 clippingType = DC_TRIVIAL;
126 }
127 else
128 {
129 clippingType = Clip->iDComplexity;
130 }
131
132 BltInfo.DestSurface = psoDest;
133 BltInfo.SourceSurface = psoSource;
134 BltInfo.PatternSurface = NULL;
135 BltInfo.XlateSourceToDest = ColorTranslation;
137
138 switch (clippingType)
139 {
140 case DC_TRIVIAL:
141 DPRINT("DC_TRIVIAL.\n");
142 BltInfo.DestRect = *DestRect;
143 BltInfo.SourcePoint = *SourcePoint;
144
145 /* Now we set the Dest Rect top and bottom based on Top Down/flip */
146 if (bTopToBottom)
147 {
148 lTmp = BltInfo.DestRect.top;
149 BltInfo.DestRect.top = BltInfo.DestRect.bottom;
150 BltInfo.DestRect.bottom = lTmp;
151 }
152
153 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
154 break;
155
156 case DC_RECT:
157 DPRINT("DC_RECT.\n");
158 // Clip the blt to the clip rectangle
159 RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
160
161 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
162 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
163
164 /* Now we set the Dest Rect top and bottom based on Top Down/flip */
165 if (bTopToBottom)
166 {
167 lTmp = BltInfo.DestRect.top;
168 BltInfo.DestRect.top = BltInfo.DestRect.bottom;
169 BltInfo.DestRect.bottom = lTmp;
170 }
171
172 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
173 break;
174
175 case DC_COMPLEX:
176 DPRINT("DC_COMPLEX.\n");
178
179 do
180 {
181 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
182
183 if (RectEnum.c > 0)
184 {
185 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
186 RECTL* prcl = &RectEnum.arcl[0];
187
188 do
189 {
190 RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect);
191
192 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
193 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
194
195 /* Now we set the Dest Rect top and bottom based on Top Down/flip */
196 if (bTopToBottom)
197 {
198 lTmp = BltInfo.DestRect.top;
199 BltInfo.DestRect.top = BltInfo.DestRect.bottom;
200 BltInfo.DestRect.bottom = lTmp;
201 }
202
203 if (!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
204 {
205 ret = FALSE;
206 goto cleanup;
207 }
208
209 prcl++;
210
211 } while (prcl < prclEnd);
212 }
213
214 } while (EnumMore);
215 ret = TRUE;
216 break;
217
218 default:
219 ASSERT(FALSE);
220 ret = FALSE;
221 break;
222 }
223
224cleanup:
225 return ret;
226}
227
230 SURFOBJ *psoDest,
231 SURFOBJ *psoSource,
232 CLIPOBJ *pco,
233 XLATEOBJ *pxlo,
235 POINTL *ptlSource)
236{
237 return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
238}
239
240
241/* EOF */
#define R3_OPINDEX_SRCCOPY
Definition: bitblt.h:27
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define APIENTRY
Definition: api.h:79
static void cleanup(void)
Definition: main.c:1335
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL APIENTRY IntEngCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSource, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDest, POINTL *ptlSource)
Definition: copybits.c:229
BOOL APIENTRY EngCopyBits(_In_ SURFOBJ *psoDest, _In_ SURFOBJ *psoSource, _In_opt_ CLIPOBJ *Clip, _In_opt_ XLATEOBJ *ColorTranslation, _In_ RECTL *DestRect, _In_ POINTL *SourcePoint)
Definition: copybits.c:19
#define ROP4_FROM_INDEX(index)
Definition: inteng.h:42
#define ASSERT(a)
Definition: mode.c:44
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
long LONG
Definition: pedump.c:60
#define DPRINT
Definition: sndvol32.h:71
PFN_DIB_BitBlt DIB_BitBltSrcCopy
Definition: dib.h:50
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
Definition: dib.h:21
RECTL DestRect
Definition: dib.h:26
SURFOBJ * SourceSurface
Definition: dib.h:23
SURFOBJ * DestSurface
Definition: dib.h:22
ROP4 Rop4
Definition: dib.h:30
SURFOBJ * PatternSurface
Definition: dib.h:24
POINTL SourcePoint
Definition: dib.h:27
XLATEOBJ * XlateSourceToDest
Definition: dib.h:25
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
FLONG flags
Definition: surface.h:10
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int ret
DIB_FUNCTIONS DibFunctionsForBitmapFormat[]
Definition: dib.c:20
BOOL APIENTRY IntEngBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 Rop4)
Definition: bitblt.c:656
#define GDIDEVFUNCS(SurfObj)
Definition: surface.h:106
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
FORCEINLINE BOOL RECTL_bIsEmptyRect(_In_ const RECTL *prcl)
Definition: rect.h:44
#define DC_TRIVIAL
Definition: winddi.h:259
#define STYPE_BITMAP
Definition: winddi.h:1175
#define CT_RECTANGLES
Definition: winddi.h:1317
ENGAPI BOOL APIENTRY CLIPOBJ_bEnum(_In_ CLIPOBJ *pco, _In_ ULONG cj, _Out_bytecap_(cj) ULONG *pul)
Definition: clip.c:319
#define DC_COMPLEX
Definition: winddi.h:261
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ * pxlo
Definition: winddi.h:3416
ENGAPI ULONG APIENTRY CLIPOBJ_cEnumStart(_Inout_ CLIPOBJ *pco, _In_ BOOL bAll, _In_ ULONG iType, _In_ ULONG iDirection, _In_ ULONG cLimit)
Definition: clip.c:255
#define DC_RECT
Definition: winddi.h:260
#define CD_ANY
Definition: winddi.h:1326
_In_ ULONG _In_ CLIPOBJ _In_ RECTL * prcl
Definition: winddi.h:3531
#define HOOK_COPYBITS
Definition: winddi.h:1429
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ _In_ RECTL * prclDest
Definition: winddi.h:3417
_In_ SURFOBJ _In_ CLIPOBJ * pco
Definition: winddi.h:3415
unsigned char BYTE
Definition: xxhash.c:193