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
*psoDest
,
39 XLATEOBJ
*ColorTranslation
,
47 INTENG_ENTER_LEAVE EnterLeaveSource
, EnterLeaveDest
;
48 SURFOBJ
*InputObj
, *OutputObj
;
49 RECTL OutputRect
, InputRect
;
57 InputRect
= *SourceRect
;
59 if(!IntEngEnter(&EnterLeaveSource
, psoSource
, &InputRect
, TRUE
, &Translate
, &InputObj
))
63 InputRect
.left
+= Translate
.x
;
64 InputRect
.right
+= Translate
.x
;
65 InputRect
.top
+= Translate
.y
;
66 InputRect
.bottom
+= Translate
.y
;
68 OutputRect
= *DestRect
;
69 if (OutputRect
.right
< OutputRect
.left
)
71 OutputRect
.left
= DestRect
->right
;
72 OutputRect
.right
= DestRect
->left
;
74 if (OutputRect
.bottom
< OutputRect
.top
)
76 OutputRect
.top
= DestRect
->bottom
;
77 OutputRect
.bottom
= DestRect
->top
;
82 if(OutputRect
.left
< Clip
->rclBounds
.left
)
84 InputRect
.left
+= Clip
->rclBounds
.left
- OutputRect
.left
;
85 OutputRect
.left
= Clip
->rclBounds
.left
;
87 if(Clip
->rclBounds
.right
< OutputRect
.right
)
89 InputRect
.right
-= OutputRect
.right
- Clip
->rclBounds
.right
;
90 OutputRect
.right
= Clip
->rclBounds
.right
;
92 if(OutputRect
.top
< Clip
->rclBounds
.top
)
94 InputRect
.top
+= Clip
->rclBounds
.top
- OutputRect
.top
;
95 OutputRect
.top
= Clip
->rclBounds
.top
;
97 if(Clip
->rclBounds
.bottom
< OutputRect
.bottom
)
99 InputRect
.bottom
-= OutputRect
.bottom
- Clip
->rclBounds
.bottom
;
100 OutputRect
.bottom
= Clip
->rclBounds
.bottom
;
104 /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
106 if(OutputRect
.right
<= OutputRect
.left
|| OutputRect
.bottom
<= OutputRect
.top
)
108 IntEngLeave(&EnterLeaveSource
);
112 if(!IntEngEnter(&EnterLeaveDest
, psoDest
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
114 IntEngLeave(&EnterLeaveSource
);
118 OutputRect
.left
= DestRect
->left
+ Translate
.x
;
119 OutputRect
.right
= DestRect
->right
+ Translate
.x
;
120 OutputRect
.top
= DestRect
->top
+ Translate
.y
;
121 OutputRect
.bottom
= DestRect
->bottom
+ Translate
.y
;
123 ClippingType
= (Clip
? Clip
->iDComplexity
: DC_TRIVIAL
);
125 DstHeight
= OutputRect
.bottom
- OutputRect
.top
;
126 DstWidth
= OutputRect
.right
- OutputRect
.left
;
127 SrcHeight
= InputRect
.bottom
- InputRect
.top
;
128 SrcWidth
= InputRect
.right
- InputRect
.left
;
133 Ret
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_TransparentBlt(
134 OutputObj
, InputObj
, &OutputRect
, &InputRect
, ColorTranslation
, iTransColor
);
139 RECTL ClipRect
, CombinedRect
;
140 RECTL InputToCombinedRect
;
142 ClipRect
.left
= Clip
->rclBounds
.left
+ Translate
.x
;
143 ClipRect
.right
= Clip
->rclBounds
.right
+ Translate
.x
;
144 ClipRect
.top
= Clip
->rclBounds
.top
+ Translate
.y
;
145 ClipRect
.bottom
= Clip
->rclBounds
.bottom
+ Translate
.y
;
146 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
148 InputToCombinedRect
.top
= InputRect
.top
+ (CombinedRect
.top
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
149 InputToCombinedRect
.bottom
= InputRect
.top
+ (CombinedRect
.bottom
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
150 InputToCombinedRect
.left
= InputRect
.left
+ (CombinedRect
.left
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
151 InputToCombinedRect
.right
= InputRect
.left
+ (CombinedRect
.right
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
152 Ret
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_TransparentBlt(
153 OutputObj
, InputObj
, &CombinedRect
, &InputToCombinedRect
, ColorTranslation
, iTransColor
);
163 if(OutputObj
== InputObj
)
165 if(OutputRect
.top
< InputRect
.top
)
167 Direction
= OutputRect
.left
< (InputRect
.left
? CD_RIGHTDOWN
: CD_LEFTDOWN
);
171 Direction
= OutputRect
.left
< (InputRect
.left
? CD_RIGHTUP
: CD_LEFTUP
);
179 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, Direction
, 0);
182 EnumMore
= CLIPOBJ_bEnum(Clip
, sizeof(RectEnum
), (PVOID
)&RectEnum
);
183 for (i
= 0; i
< RectEnum
.c
; i
++)
185 RECTL ClipRect
, CombinedRect
;
186 RECTL InputToCombinedRect
;
188 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
189 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
190 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
191 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
192 if (EngIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
194 InputToCombinedRect
.top
= InputRect
.top
+ (CombinedRect
.top
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
195 InputToCombinedRect
.bottom
= InputRect
.top
+ (CombinedRect
.bottom
- OutputRect
.top
) * SrcHeight
/ DstHeight
;
196 InputToCombinedRect
.left
= InputRect
.left
+ (CombinedRect
.left
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
197 InputToCombinedRect
.right
= InputRect
.left
+ (CombinedRect
.right
- OutputRect
.left
) * SrcWidth
/ DstWidth
;
199 Ret
= DibFunctionsForBitmapFormat
[psoDest
->iBitmapFormat
].DIB_TransparentBlt(
200 OutputObj
, InputObj
, &CombinedRect
, &InputToCombinedRect
, ColorTranslation
, iTransColor
);
207 } while(EnumMore
&& Ret
);
217 IntEngLeave(&EnterLeaveDest
);
218 IntEngLeave(&EnterLeaveSource
);
224 IntEngTransparentBlt(SURFOBJ
*psoDest
,
227 XLATEOBJ
*ColorTranslation
,
234 RECTL OutputRect
, InputClippedRect
;
236 SURFACE
*psurfSource
;
238 LONG InputClWidth
, InputClHeight
, InputWidth
, InputHeight
;
244 psurfDest
= CONTAINING_RECORD(psoDest
, SURFACE
, SurfObj
);
245 psurfSource
= CONTAINING_RECORD(psoSource
, SURFACE
, SurfObj
);
250 InputClippedRect
= *DestRect
;
251 if(InputClippedRect
.right
< InputClippedRect
.left
)
253 InputClippedRect
.left
= DestRect
->right
;
254 InputClippedRect
.right
= DestRect
->left
;
256 if(InputClippedRect
.bottom
< InputClippedRect
.top
)
258 InputClippedRect
.top
= DestRect
->bottom
;
259 InputClippedRect
.bottom
= DestRect
->top
;
262 InputRect
= *SourceRect
;
263 /* Clip against the bounds of the clipping region so we won't try to write
264 * outside the surface */
267 if(!EngIntersectRect(&OutputRect
, &InputClippedRect
, &Clip
->rclBounds
))
271 /* Update source rect */
272 InputClWidth
= InputClippedRect
.right
- InputClippedRect
.left
;
273 InputClHeight
= InputClippedRect
.bottom
- InputClippedRect
.top
;
274 InputWidth
= InputRect
.right
- InputRect
.left
;
275 InputHeight
= InputRect
.bottom
- InputRect
.top
;
277 InputRect
.left
+= (InputWidth
* (OutputRect
.left
- InputClippedRect
.left
)) / InputClWidth
;
278 InputRect
.right
-= (InputWidth
* (InputClippedRect
.right
- OutputRect
.right
)) / InputClWidth
;
279 InputRect
.top
+= (InputHeight
* (OutputRect
.top
- InputClippedRect
.top
)) / InputClHeight
;
280 InputRect
.bottom
-= (InputHeight
* (InputClippedRect
.bottom
- OutputRect
.bottom
)) / InputClHeight
;
284 OutputRect
= InputClippedRect
;
287 if(psoSource
!= psoDest
)
289 SURFACE_LockBitmapBits(psurfSource
);
290 MouseSafetyOnDrawStart(psoSource
, InputRect
.left
, InputRect
.top
,
291 InputRect
.right
, InputRect
.bottom
);
293 SURFACE_LockBitmapBits(psurfDest
);
294 MouseSafetyOnDrawStart(psoDest
, OutputRect
.left
, OutputRect
.top
,
295 OutputRect
.right
, OutputRect
.bottom
);
297 if(psurfDest
->flHooks
& HOOK_TRANSPARENTBLT
)
299 Ret
= GDIDEVFUNCS(psoDest
).TransparentBlt(
300 psoDest
, psoSource
, Clip
, ColorTranslation
, &OutputRect
,
301 &InputRect
, iTransColor
, Reserved
);
308 Ret
= EngTransparentBlt(psoDest
, psoSource
, Clip
, ColorTranslation
,
309 &OutputRect
, &InputRect
, iTransColor
, Reserved
);
312 MouseSafetyOnDrawEnd(psoDest
);
313 SURFACE_UnlockBitmapBits(psurfDest
);
314 if(psoSource
!= psoDest
)
316 MouseSafetyOnDrawEnd(psoSource
);
317 SURFACE_UnlockBitmapBits(psurfSource
);