2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: GDI TransparentBlt Function
24 * FILE: subsys/win32k/eng/transblt.c
25 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
33 EngTransparentBlt(SURFOBJ
*Dest
,
36 XLATEOBJ
*ColorTranslation
,
44 INTENG_ENTER_LEAVE EnterLeaveSource
, EnterLeaveDest
;
45 SURFOBJ
*InputObj
, *OutputObj
;
46 RECTL OutputRect
, InputRect
;
47 POINTL Translate
, InputPoint
;
50 InputRect
.right
= DestRect
->right
- DestRect
->left
;
52 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
54 if(!IntEngEnter(&EnterLeaveSource
, Source
, &InputRect
, TRUE
, &Translate
, &InputObj
))
59 InputPoint
.x
= SourceRect
->left
+ Translate
.x
;
60 InputPoint
.y
= SourceRect
->top
+ Translate
.y
;
62 OutputRect
= *DestRect
;
65 if(OutputRect
.left
< Clip
->rclBounds
.left
)
67 InputRect
.left
+= Clip
->rclBounds
.left
- OutputRect
.left
;
68 InputPoint
.x
+= Clip
->rclBounds
.left
- OutputRect
.left
;
69 OutputRect
.left
= Clip
->rclBounds
.left
;
71 if(Clip
->rclBounds
.right
< OutputRect
.right
)
73 InputRect
.right
-= OutputRect
.right
- Clip
->rclBounds
.right
;
74 OutputRect
.right
= Clip
->rclBounds
.right
;
76 if(OutputRect
.top
< Clip
->rclBounds
.top
)
78 InputRect
.top
+= Clip
->rclBounds
.top
- OutputRect
.top
;
79 InputPoint
.y
+= Clip
->rclBounds
.top
- OutputRect
.top
;
80 OutputRect
.top
= Clip
->rclBounds
.top
;
82 if(Clip
->rclBounds
.bottom
< OutputRect
.bottom
)
84 InputRect
.bottom
-= OutputRect
.bottom
- Clip
->rclBounds
.bottom
;
85 OutputRect
.bottom
= Clip
->rclBounds
.bottom
;
89 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
91 if(OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
93 IntEngLeave(&EnterLeaveSource
);
97 if(!IntEngEnter(&EnterLeaveDest
, Dest
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
99 IntEngLeave(&EnterLeaveSource
);
103 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
104 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
105 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
106 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
108 ClippingType
= (Clip
? Clip
->iDComplexity
: DC_TRIVIAL
);
114 Ret
= DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_TransparentBlt(
115 OutputObj
, InputObj
, &OutputRect
, &InputPoint
, ColorTranslation
, iTransColor
);
120 RECTL ClipRect
, CombinedRect
;
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 EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
);
128 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
129 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
130 Ret
= DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_TransparentBlt(
131 OutputObj
, InputObj
, &CombinedRect
, &Pt
, ColorTranslation
, iTransColor
);
141 if(OutputObj
== InputObj
)
143 if(OutputRect
.top
< InputPoint
.y
)
145 Direction
= OutputRect
.left
< (InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
);
149 Direction
= OutputRect
.left
< (InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
);
157 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, Direction
, 0);
160 EnumMore
= CLIPOBJ_bEnum(Clip
, sizeof(RectEnum
), (PVOID
)&RectEnum
);
161 for (i
= 0; i
< RectEnum
.c
; i
++)
163 RECTL ClipRect
, CombinedRect
;
165 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
166 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
167 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
168 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
169 EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
);
170 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
171 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
172 Ret
= DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_TransparentBlt(
173 OutputObj
, InputObj
, &CombinedRect
, &Pt
, ColorTranslation
, iTransColor
);
179 } while(EnumMore
&& Ret
);
189 IntEngLeave(&EnterLeaveDest
);
190 IntEngLeave(&EnterLeaveSource
);
196 IntEngTransparentBlt(BITMAPOBJ
*DestObj
,
197 BITMAPOBJ
*SourceObj
,
199 XLATEOBJ
*ColorTranslation
,
206 RECTL OutputRect
, InputClippedRect
;
214 DestSurf
= &DestObj
->SurfObj
;
215 SourceSurf
= &SourceObj
->SurfObj
;
220 InputClippedRect
= *DestRect
;
221 if(InputClippedRect
.right
< InputClippedRect
.left
)
223 InputClippedRect
.left
= DestRect
->right
;
224 InputClippedRect
.right
= DestRect
->left
;
226 if(InputClippedRect
.bottom
< InputClippedRect
.top
)
228 InputClippedRect
.top
= DestRect
->bottom
;
229 InputClippedRect
.bottom
= DestRect
->top
;
232 /* Clip against the bounds of the clipping region so we won't try to write
233 * outside the surface */
236 if(!EngIntersectRect(&OutputRect
, &InputClippedRect
, &Clip
->rclBounds
))
240 SourceRect
->left
+= OutputRect
.left
- DestRect
->left
;
241 SourceRect
->top
+= OutputRect
.top
- DestRect
->top
;
242 SourceRect
->right
+= OutputRect
.left
- DestRect
->left
;
243 SourceRect
->bottom
+= OutputRect
.top
- DestRect
->top
;
247 OutputRect
= *DestRect
;
250 if(SourceSurf
!= DestSurf
)
252 MouseSafetyOnDrawStart(SourceSurf
, SourceRect
->left
, SourceRect
->top
,
253 SourceRect
->right
, SourceRect
->bottom
);
255 MouseSafetyOnDrawStart(DestSurf
, OutputRect
.left
, OutputRect
.top
,
256 OutputRect
.right
, OutputRect
.bottom
);
258 if(DestObj
->flHooks
& HOOK_TRANSPARENTBLT
)
260 Ret
= GDIDEVFUNCS(DestSurf
).TransparentBlt(
261 DestSurf
, SourceSurf
, Clip
, ColorTranslation
, &OutputRect
,
262 SourceRect
, iTransColor
, Reserved
);
269 Ret
= EngTransparentBlt(DestSurf
, SourceSurf
, Clip
, ColorTranslation
,
270 &OutputRect
, SourceRect
, iTransColor
, Reserved
);
275 /* Dummy BitBlt to let driver know that something has changed.
276 0x00AA0029 is the Rop for D (no-op) */
277 if (DestObj
->flHooks
& HOOK_BITBLT
)
279 GDIDEVFUNCS(DestSurf
).BitBlt(
280 DestSurf
, NULL
, NULL
, Clip
, ColorTranslation
,
281 &OutputRect
, NULL
, NULL
, NULL
, NULL
, ROP_NOOP
);
285 MouseSafetyOnDrawEnd(DestSurf
);
286 if(SourceSurf
!= DestSurf
)
288 MouseSafetyOnDrawEnd(SourceSurf
);