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)
36 EngTransparentBlt(SURFOBJ
*Dest
,
39 XLATEOBJ
*ColorTranslation
,
47 INTENG_ENTER_LEAVE EnterLeaveSource
, EnterLeaveDest
;
48 SURFOBJ
*InputObj
, *OutputObj
;
49 RECTL OutputRect
, InputRect
;
50 POINTL Translate
, InputPoint
;
53 InputRect
.right
= DestRect
->right
- DestRect
->left
;
55 InputRect
.bottom
= DestRect
->bottom
- DestRect
->top
;
57 if(!IntEngEnter(&EnterLeaveSource
, Source
, &InputRect
, TRUE
, &Translate
, &InputObj
))
62 InputPoint
.x
= SourceRect
->left
+ Translate
.x
;
63 InputPoint
.y
= SourceRect
->top
+ Translate
.y
;
65 OutputRect
= *DestRect
;
68 if(OutputRect
.left
< Clip
->rclBounds
.left
)
70 InputRect
.left
+= Clip
->rclBounds
.left
- OutputRect
.left
;
71 InputPoint
.x
+= Clip
->rclBounds
.left
- OutputRect
.left
;
72 OutputRect
.left
= Clip
->rclBounds
.left
;
74 if(Clip
->rclBounds
.right
< OutputRect
.right
)
76 InputRect
.right
-= OutputRect
.right
- Clip
->rclBounds
.right
;
77 OutputRect
.right
= Clip
->rclBounds
.right
;
79 if(OutputRect
.top
< Clip
->rclBounds
.top
)
81 InputRect
.top
+= Clip
->rclBounds
.top
- OutputRect
.top
;
82 InputPoint
.y
+= Clip
->rclBounds
.top
- OutputRect
.top
;
83 OutputRect
.top
= Clip
->rclBounds
.top
;
85 if(Clip
->rclBounds
.bottom
< OutputRect
.bottom
)
87 InputRect
.bottom
-= OutputRect
.bottom
- Clip
->rclBounds
.bottom
;
88 OutputRect
.bottom
= Clip
->rclBounds
.bottom
;
92 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
94 if(OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
96 IntEngLeave(&EnterLeaveSource
);
100 if(!IntEngEnter(&EnterLeaveDest
, Dest
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
102 IntEngLeave(&EnterLeaveSource
);
106 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
107 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
108 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
109 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
111 ClippingType
= (Clip
? Clip
->iDComplexity
: DC_TRIVIAL
);
117 Ret
= DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_TransparentBlt(
118 OutputObj
, InputObj
, &OutputRect
, &InputPoint
, ColorTranslation
, iTransColor
);
123 RECTL ClipRect
, CombinedRect
;
126 ClipRect
.left
= Clip
->rclBounds
.left
+ Translate
.x
;
127 ClipRect
.right
= Clip
->rclBounds
.right
+ Translate
.x
;
128 ClipRect
.top
= Clip
->rclBounds
.top
+ Translate
.y
;
129 ClipRect
.bottom
= Clip
->rclBounds
.bottom
+ Translate
.y
;
130 EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
);
131 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
132 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
133 Ret
= DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_TransparentBlt(
134 OutputObj
, InputObj
, &CombinedRect
, &Pt
, ColorTranslation
, iTransColor
);
144 if(OutputObj
== InputObj
)
146 if(OutputRect
.top
< InputPoint
.y
)
148 Direction
= OutputRect
.left
< (InputPoint
.x
? CD_RIGHTDOWN
: CD_LEFTDOWN
);
152 Direction
= OutputRect
.left
< (InputPoint
.x
? CD_RIGHTUP
: CD_LEFTUP
);
160 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, Direction
, 0);
163 EnumMore
= CLIPOBJ_bEnum(Clip
, sizeof(RectEnum
), (PVOID
)&RectEnum
);
164 for (i
= 0; i
< RectEnum
.c
; i
++)
166 RECTL ClipRect
, CombinedRect
;
168 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
169 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
170 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
171 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
172 EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
);
173 Pt
.x
= InputPoint
.x
+ CombinedRect
.left
- OutputRect
.left
;
174 Pt
.y
= InputPoint
.y
+ CombinedRect
.top
- OutputRect
.top
;
175 Ret
= DibFunctionsForBitmapFormat
[Dest
->iBitmapFormat
].DIB_TransparentBlt(
176 OutputObj
, InputObj
, &CombinedRect
, &Pt
, ColorTranslation
, iTransColor
);
182 } while(EnumMore
&& Ret
);
192 IntEngLeave(&EnterLeaveDest
);
193 IntEngLeave(&EnterLeaveSource
);
199 IntEngTransparentBlt(SURFOBJ
*DestSurf
,
202 XLATEOBJ
*ColorTranslation
,
209 RECTL OutputRect
, InputClippedRect
;
211 BITMAPOBJ
*SourceObj
;
217 DestObj
= CONTAINING_RECORD(DestSurf
, BITMAPOBJ
, SurfObj
);
218 SourceObj
= CONTAINING_RECORD(SourceSurf
, BITMAPOBJ
, SurfObj
);
223 InputClippedRect
= *DestRect
;
224 if(InputClippedRect
.right
< InputClippedRect
.left
)
226 InputClippedRect
.left
= DestRect
->right
;
227 InputClippedRect
.right
= DestRect
->left
;
229 if(InputClippedRect
.bottom
< InputClippedRect
.top
)
231 InputClippedRect
.top
= DestRect
->bottom
;
232 InputClippedRect
.bottom
= DestRect
->top
;
235 /* Clip against the bounds of the clipping region so we won't try to write
236 * outside the surface */
239 if(!EngIntersectRect(&OutputRect
, &InputClippedRect
, &Clip
->rclBounds
))
243 SourceRect
->left
+= OutputRect
.left
- DestRect
->left
;
244 SourceRect
->top
+= OutputRect
.top
- DestRect
->top
;
245 SourceRect
->right
+= OutputRect
.left
- DestRect
->left
;
246 SourceRect
->bottom
+= OutputRect
.top
- DestRect
->top
;
250 OutputRect
= *DestRect
;
253 if(SourceSurf
!= DestSurf
)
255 BITMAPOBJ_LockBitmapBits(SourceObj
);
256 MouseSafetyOnDrawStart(SourceSurf
, SourceRect
->left
, SourceRect
->top
,
257 SourceRect
->right
, SourceRect
->bottom
);
259 BITMAPOBJ_LockBitmapBits(DestObj
);
260 MouseSafetyOnDrawStart(DestSurf
, OutputRect
.left
, OutputRect
.top
,
261 OutputRect
.right
, OutputRect
.bottom
);
263 if(DestObj
->flHooks
& HOOK_TRANSPARENTBLT
)
265 Ret
= GDIDEVFUNCS(DestSurf
).TransparentBlt(
266 DestSurf
, SourceSurf
, Clip
, ColorTranslation
, &OutputRect
,
267 SourceRect
, iTransColor
, Reserved
);
274 Ret
= EngTransparentBlt(DestSurf
, SourceSurf
, Clip
, ColorTranslation
,
275 &OutputRect
, SourceRect
, iTransColor
, Reserved
);
278 MouseSafetyOnDrawEnd(DestSurf
);
279 BITMAPOBJ_UnlockBitmapBits(DestObj
);
280 if(SourceSurf
!= DestSurf
)
282 MouseSafetyOnDrawEnd(SourceSurf
);
283 BITMAPOBJ_UnlockBitmapBits(SourceObj
);