ReactOS 0.4.16-dev-306-g647d351
transblt.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 TransparentBlt Function
5 * FILE: win32ss/gdi/eng/transblt.c
6 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 */
8
9#include <win32k.h>
10
11#define NDEBUG
12#include <debug.h>
13
14BOOL
17 SURFOBJ *psoDest,
18 SURFOBJ *psoSource,
19 CLIPOBJ *Clip,
20 XLATEOBJ *ColorTranslation,
21 PRECTL DestRect,
22 PRECTL SourceRect,
25{
26 BOOL Ret = TRUE;
27 BYTE ClippingType;
28 INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest;
29 SURFOBJ *InputObj, *OutputObj;
30 RECTL OutputRect, InputRect;
31 POINTL Translate;
32
33 LONG DstHeight;
34 LONG DstWidth;
35 LONG SrcHeight;
36 LONG SrcWidth;
37
38 InputRect = *SourceRect;
39
40 if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
41 {
42 return FALSE;
43 }
44 InputRect.left += Translate.x;
45 InputRect.right += Translate.x;
46 InputRect.top += Translate.y;
47 InputRect.bottom += Translate.y;
48
49 OutputRect = *DestRect;
50 if (OutputRect.right < OutputRect.left)
51 {
52 OutputRect.left = DestRect->right;
53 OutputRect.right = DestRect->left;
54 }
55 if (OutputRect.bottom < OutputRect.top)
56 {
57 OutputRect.top = DestRect->bottom;
58 OutputRect.bottom = DestRect->top;
59 }
60
61 if (Clip)
62 {
63 if (OutputRect.left < Clip->rclBounds.left)
64 {
65 InputRect.left += Clip->rclBounds.left - OutputRect.left;
66 OutputRect.left = Clip->rclBounds.left;
67 }
68 if (Clip->rclBounds.right < OutputRect.right)
69 {
70 InputRect.right -= OutputRect.right - Clip->rclBounds.right;
71 OutputRect.right = Clip->rclBounds.right;
72 }
73 if (OutputRect.top < Clip->rclBounds.top)
74 {
75 InputRect.top += Clip->rclBounds.top - OutputRect.top;
76 OutputRect.top = Clip->rclBounds.top;
77 }
78 if (Clip->rclBounds.bottom < OutputRect.bottom)
79 {
80 InputRect.bottom -= OutputRect.bottom - Clip->rclBounds.bottom;
81 OutputRect.bottom = Clip->rclBounds.bottom;
82 }
83 }
84
85 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
86 nothing to do */
87 if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
88 {
89 IntEngLeave(&EnterLeaveSource);
90 return TRUE;
91 }
92
93 if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
94 {
95 IntEngLeave(&EnterLeaveSource);
96 return FALSE;
97 }
98
99 OutputRect.left = DestRect->left + Translate.x;
100 OutputRect.right = DestRect->right + Translate.x;
101 OutputRect.top = DestRect->top + Translate.y;
102 OutputRect.bottom = DestRect->bottom + Translate.y;
103
104 ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL);
105
106 DstHeight = OutputRect.bottom - OutputRect.top;
107 DstWidth = OutputRect.right - OutputRect.left;
108 SrcHeight = InputRect.bottom - InputRect.top;
109 SrcWidth = InputRect.right - InputRect.left;
110 switch (ClippingType)
111 {
112 case DC_TRIVIAL:
113 {
115 OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor);
116 break;
117 }
118 case DC_RECT:
119 {
120 RECTL ClipRect, CombinedRect;
121 RECTL InputToCombinedRect;
122
123 ClipRect.left = Clip->rclBounds.left + Translate.x;
124 ClipRect.right = Clip->rclBounds.right + Translate.x;
125 ClipRect.top = Clip->rclBounds.top + Translate.y;
126 ClipRect.bottom = Clip->rclBounds.bottom + Translate.y;
127 if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
128 {
129 InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
130 InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
131 InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
132 InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
134 OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
135 }
136 break;
137 }
138 case DC_COMPLEX:
139 {
141 RECT_ENUM RectEnum;
142 BOOL EnumMore;
143
144 if (OutputObj == InputObj)
145 {
146 if (OutputRect.top < InputRect.top)
147 {
148 Direction = OutputRect.left < (InputRect.left ? CD_RIGHTDOWN : CD_LEFTDOWN);
149 }
150 else
151 {
152 Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP);
153 }
154 }
155 else
156 {
158 }
159
161 do
162 {
163 EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID)&RectEnum);
164 for (i = 0; i < RectEnum.c; i++)
165 {
166 RECTL ClipRect, CombinedRect;
167 RECTL InputToCombinedRect;
168
169 ClipRect.left = RectEnum.arcl[i].left + Translate.x;
170 ClipRect.right = RectEnum.arcl[i].right + Translate.x;
171 ClipRect.top = RectEnum.arcl[i].top + Translate.y;
172 ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
173 if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
174 {
175 InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
176 InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
177 InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
178 InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
179
181 OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor);
182 if (!Ret)
183 {
184 break;
185 }
186 }
187 }
188 }
189 while (EnumMore && Ret);
190 break;
191 }
192 default:
193 {
194 Ret = FALSE;
195 break;
196 }
197 }
198
199 IntEngLeave(&EnterLeaveDest);
200 IntEngLeave(&EnterLeaveSource);
201
202 return Ret;
203}
204
205BOOL
208 SURFOBJ *psoDest,
209 SURFOBJ *psoSource,
210 CLIPOBJ *Clip,
211 XLATEOBJ *ColorTranslation,
212 PRECTL DestRect,
213 PRECTL SourceRect,
216{
217 BOOL Ret;
218 RECTL OutputRect, InputClippedRect;
219 SURFACE *psurfDest;
220 SURFACE *psurfSource;
221 RECTL InputRect;
222 LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
223
224 ASSERT(psoDest);
225 ASSERT(psoSource);
226 ASSERT(DestRect);
227
228 psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
229 psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
230
231 ASSERT(psurfDest);
232 ASSERT(psurfSource);
233
234 /* If no clip object is given, use trivial one */
235 if (!Clip) Clip = (CLIPOBJ *)&gxcoTrivial;
236
237 InputClippedRect = *DestRect;
238 if (InputClippedRect.right < InputClippedRect.left)
239 {
240 InputClippedRect.left = DestRect->right;
241 InputClippedRect.right = DestRect->left;
242 }
243 if (InputClippedRect.bottom < InputClippedRect.top)
244 {
245 InputClippedRect.top = DestRect->bottom;
246 InputClippedRect.bottom = DestRect->top;
247 }
248
249 InputRect = *SourceRect;
250 /* Clip against the bounds of the clipping region so we won't try to write
251 * outside the surface */
252 if (Clip->iDComplexity != DC_TRIVIAL)
253 {
254 if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds))
255 {
256 return TRUE;
257 }
258 /* Update source rect */
259 InputClWidth = InputClippedRect.right - InputClippedRect.left;
260 InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
261 InputWidth = InputRect.right - InputRect.left;
262 InputHeight = InputRect.bottom - InputRect.top;
263
264 InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) / InputClWidth;
265 InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) / InputClWidth;
266 InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) / InputClHeight;
267 InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom)) / InputClHeight;
268 }
269 else
270 {
271 OutputRect = InputClippedRect;
272 }
273
274 if (psurfDest->flags & HOOK_TRANSPARENTBLT)
275 {
276 Ret = GDIDEVFUNCS(psoDest).TransparentBlt(psoDest,
277 psoSource,
278 Clip,
279 ColorTranslation,
280 &OutputRect,
281 &InputRect,
283 Reserved);
284 }
285 else
286 Ret = FALSE;
287
288 if (!Ret)
289 {
290 Ret = EngTransparentBlt(psoDest,
291 psoSource,
292 Clip,
293 ColorTranslation,
294 &OutputRect,
295 &InputRect,
297 Reserved);
298 }
299
300 return Ret;
301}
302
303/* EOF */
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define APIENTRY
Definition: api.h:79
BOOL APIENTRY IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, SURFOBJ *psoDest, RECTL *DestRect, BOOL ReadOnly, POINTL *Translate, SURFOBJ **ppsoOutput)
Definition: engmisc.c:15
BOOL APIENTRY IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
Definition: engmisc.c:162
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL APIENTRY EngTransparentBlt(SURFOBJ *psoDest, SURFOBJ *psoSource, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, PRECTL DestRect, PRECTL SourceRect, ULONG iTransColor, ULONG Reserved)
Definition: transblt.c:16
BOOL FASTCALL IntEngTransparentBlt(SURFOBJ *psoDest, SURFOBJ *psoSource, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, PRECTL DestRect, PRECTL SourceRect, ULONG iTransColor, ULONG Reserved)
Definition: transblt.c:207
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT(a)
Definition: mode.c:44
#define FASTCALL
Definition: nt_native.h:50
long LONG
Definition: pedump.c:60
PFN_DIB_TransparentBlt DIB_TransparentBlt
Definition: dib.h:52
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
BYTE iDComplexity
Definition: winddi.h:278
RECTL rclBounds
Definition: winddi.h:277
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
FLONG flags
Definition: surface.h:10
ULONG iBitmapFormat
Definition: winddi.h:1215
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction
DIB_FUNCTIONS DibFunctionsForBitmapFormat[]
Definition: dib.c:20
XCLIPOBJ gxcoTrivial
Definition: bitblt.c:20
#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
#define DC_TRIVIAL
Definition: winddi.h:259
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ _In_ RECTL _In_ RECTL _In_ ULONG iTransColor
Definition: winddi.h:4195
#define CT_RECTANGLES
Definition: winddi.h:1317
#define HOOK_TRANSPARENTBLT
Definition: winddi.h:1434
ENGAPI BOOL APIENTRY CLIPOBJ_bEnum(_In_ CLIPOBJ *pco, _In_ ULONG cj, _Out_bytecap_(cj) ULONG *pul)
Definition: clip.c:319
#define CD_RIGHTUP
Definition: winddi.h:1323
#define CD_LEFTDOWN
Definition: winddi.h:1321
#define DC_COMPLEX
Definition: winddi.h:261
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_RIGHTDOWN
Definition: winddi.h:1320
#define CD_ANY
Definition: winddi.h:1326
#define CD_LEFTUP
Definition: winddi.h:1325
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
unsigned char BYTE
Definition: xxhash.c:193