ReactOS  0.4.14-dev-384-g5b37caa
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 
14 BOOL
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  {
140  ULONG Direction, i;
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  {
157  Direction = CD_ANY;
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 
205 BOOL
206 FASTCALL
208  SURFOBJ *psoDest,
209  SURFOBJ *psoSource,
210  CLIPOBJ *Clip,
211  XLATEOBJ *ColorTranslation,
212  PRECTL DestRect,
213  PRECTL SourceRect,
215  ULONG Reserved)
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,
282  iTransColor,
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,
296  iTransColor,
297  Reserved);
298  }
299 
300  return Ret;
301 }
302 
303 /* EOF */
BOOL APIENTRY EngTransparentBlt(SURFOBJ *psoDest, SURFOBJ *psoSource, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, PRECTL DestRect, PRECTL SourceRect, ULONG iTransColor, ULONG Reserved)
Definition: transblt.c:16
#define TRUE
Definition: types.h:120
XCLIPOBJ gxcoTrivial
Definition: bitblt.c:15
#define HOOK_TRANSPARENTBLT
Definition: winddi.h:1434
PFN_DIB_TransparentBlt DIB_TransparentBlt
Definition: dib.h:52
#define DC_TRIVIAL
Definition: winddi.h:259
long bottom
Definition: polytest.cpp:53
ULONG iBitmapFormat
Definition: winddi.h:1215
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ _In_ RECTL _In_ RECTL _In_ ULONG iTransColor
Definition: winddi.h:4190
#define FASTCALL
Definition: nt_native.h:50
LONG y
Definition: windef.h:315
long right
Definition: polytest.cpp:53
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
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define CD_RIGHTDOWN
Definition: winddi.h:1320
long top
Definition: polytest.cpp:53
RECTL rclBounds
Definition: winddi.h:277
BOOL FASTCALL IntEngTransparentBlt(SURFOBJ *psoDest, SURFOBJ *psoSource, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, PRECTL DestRect, PRECTL SourceRect, ULONG iTransColor, ULONG Reserved)
Definition: transblt.c:207
#define CT_RECTANGLES
Definition: winddi.h:1317
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
long left
Definition: polytest.cpp:53
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define DC_RECT
Definition: winddi.h:260
#define CD_RIGHTUP
Definition: winddi.h:1323
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 GDIDEVFUNCS(SurfObj)
Definition: surface.h:106
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION Direction
Definition: mmfuncs.h:773
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
LONG x
Definition: windef.h:314
BOOL APIENTRY IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, SURFOBJ *psoDest, RECTL *DestRect, BOOL ReadOnly, POINTL *Translate, SURFOBJ **ppsoOutput)
Definition: engmisc.c:15
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define CD_LEFTDOWN
Definition: winddi.h:1321
unsigned char BYTE
Definition: mem.h:68
#define CD_LEFTUP
Definition: winddi.h:1325
#define DC_COMPLEX
Definition: winddi.h:261
BYTE iDComplexity
Definition: winddi.h:278
DIB_FUNCTIONS DibFunctionsForBitmapFormat[]
Definition: dib.c:20
FLONG flags
Definition: surface.h:10
unsigned int ULONG
Definition: retypes.h:1
BOOL APIENTRY IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
Definition: engmisc.c:162
ENGAPI BOOL APIENTRY CLIPOBJ_bEnum(_In_ CLIPOBJ *pco, _In_ ULONG cj, _Out_bytecap_(cj) ULONG *pul)
Definition: clip.c:319
#define APIENTRY
Definition: api.h:79
#define CD_ANY
Definition: winddi.h:1326