2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI alpha blending functions
5 * FILE: subsystems/win32/win32k/eng/alphablend.c
6 * PROGRAMER: Jason Filby
20 EngAlphaBlend(IN SURFOBJ
*psoDest
,
21 IN SURFOBJ
*psoSource
,
22 IN CLIPOBJ
*ClipRegion
,
23 IN XLATEOBJ
*ColorTranslation
,
26 IN BLENDOBJ
*BlendObj
)
34 INTENG_ENTER_LEAVE EnterLeaveSource
;
35 INTENG_ENTER_LEAVE EnterLeaveDest
;
44 DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", psoDest
, psoSource
, ClipRegion
, ColorTranslation
);
45 DPRINT(" DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
46 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
,
47 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
);
48 DPRINT(" BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj
->BlendFunction
.BlendOp
,
49 BlendObj
->BlendFunction
.BlendFlags
, BlendObj
->BlendFunction
.SourceConstantAlpha
,
50 BlendObj
->BlendFunction
.AlphaFormat
);
53 OutputRect
= *DestRect
;
54 if (OutputRect
.right
< OutputRect
.left
)
56 OutputRect
.left
= DestRect
->right
;
57 OutputRect
.right
= DestRect
->left
;
59 if (OutputRect
.bottom
< OutputRect
.top
)
61 OutputRect
.left
= DestRect
->right
;
62 OutputRect
.right
= DestRect
->left
;
66 InputRect
= *SourceRect
;
67 if ( (InputRect
.top
< 0) || (InputRect
.bottom
< 0) ||
68 (InputRect
.left
< 0) || (InputRect
.right
< 0) ||
69 InputRect
.right
> psoSource
->sizlBitmap
.cx
||
70 InputRect
.bottom
> psoSource
->sizlBitmap
.cy
)
72 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
76 if (psoDest
== psoSource
&&
77 !(OutputRect
.left
>= SourceRect
->right
|| InputRect
.left
>= OutputRect
.right
||
78 OutputRect
.top
>= SourceRect
->bottom
|| InputRect
.top
>= OutputRect
.bottom
))
80 DPRINT1("Source and destination rectangles overlap!\n");
84 if (BlendObj
->BlendFunction
.BlendOp
!= AC_SRC_OVER
)
86 DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj
->BlendFunction
.BlendOp
);
89 if (BlendObj
->BlendFunction
.BlendFlags
!= 0)
91 DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj
->BlendFunction
.BlendFlags
);
94 if ((BlendObj
->BlendFunction
.AlphaFormat
& ~AC_SRC_ALPHA
) != 0)
96 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj
->BlendFunction
.AlphaFormat
);
100 /* Check if there is anything to draw */
101 if (ClipRegion
!= NULL
&&
102 (ClipRegion
->rclBounds
.left
>= ClipRegion
->rclBounds
.right
||
103 ClipRegion
->rclBounds
.top
>= ClipRegion
->rclBounds
.bottom
))
109 /* Now call the DIB function */
110 if (!IntEngEnter(&EnterLeaveSource
, psoSource
, &InputRect
, TRUE
, &Translate
, &InputObj
))
114 InputRect
.left
+= Translate
.x
;
115 InputRect
.right
+= Translate
.x
;
116 InputRect
.top
+= Translate
.y
;
117 InputRect
.bottom
+= Translate
.y
;
119 if (!IntEngEnter(&EnterLeaveDest
, psoDest
, &OutputRect
, FALSE
, &Translate
, &OutputObj
))
123 OutputRect
.left
+= Translate
.x
;
124 OutputRect
.right
+= Translate
.x
;
125 OutputRect
.top
+= Translate
.y
;
126 OutputRect
.bottom
+= Translate
.y
;
129 ClippingType
= (ClipRegion
== NULL
) ? DC_TRIVIAL
: ClipRegion
->iDComplexity
;
130 switch (ClippingType
)
133 Ret
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_AlphaBlend(
134 OutputObj
, InputObj
, &OutputRect
, &InputRect
, ClipRegion
, ColorTranslation
, BlendObj
);
138 ClipRect
.left
= ClipRegion
->rclBounds
.left
+ Translate
.x
;
139 ClipRect
.right
= ClipRegion
->rclBounds
.right
+ Translate
.x
;
140 ClipRect
.top
= ClipRegion
->rclBounds
.top
+ Translate
.y
;
141 ClipRect
.bottom
= ClipRegion
->rclBounds
.bottom
+ Translate
.y
;
142 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
144 Rect
.left
= InputRect
.left
+ CombinedRect
.left
- OutputRect
.left
;
145 Rect
.right
= InputRect
.right
+ CombinedRect
.right
- OutputRect
.right
;
146 Rect
.top
= InputRect
.top
+ CombinedRect
.top
- OutputRect
.top
;
147 Rect
.bottom
= InputRect
.bottom
+ CombinedRect
.bottom
- OutputRect
.bottom
;
148 Ret
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_AlphaBlend(
149 OutputObj
, InputObj
, &CombinedRect
, &Rect
, ClipRegion
, ColorTranslation
, BlendObj
);
155 CLIPOBJ_cEnumStart(ClipRegion
, FALSE
, CT_RECTANGLES
, CD_ANY
, 0);
158 EnumMore
= CLIPOBJ_bEnum(ClipRegion
,(ULONG
) sizeof(RectEnum
),
161 for (i
= 0; i
< RectEnum
.c
; i
++)
163 ClipRect
.left
= RectEnum
.arcl
[i
].left
+ Translate
.x
;
164 ClipRect
.right
= RectEnum
.arcl
[i
].right
+ Translate
.x
;
165 ClipRect
.top
= RectEnum
.arcl
[i
].top
+ Translate
.y
;
166 ClipRect
.bottom
= RectEnum
.arcl
[i
].bottom
+ Translate
.y
;
167 if (RECTL_bIntersectRect(&CombinedRect
, &OutputRect
, &ClipRect
))
169 Rect
.left
= InputRect
.left
+ CombinedRect
.left
- OutputRect
.left
;
170 Rect
.right
= InputRect
.right
+ CombinedRect
.right
- OutputRect
.right
;
171 Rect
.top
= InputRect
.top
+ CombinedRect
.top
- OutputRect
.top
;
172 Rect
.bottom
= InputRect
.bottom
+ CombinedRect
.bottom
- OutputRect
.bottom
;
173 Ret
= DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_AlphaBlend(
174 OutputObj
, InputObj
, &CombinedRect
, &Rect
, ClipRegion
, ColorTranslation
, BlendObj
) && Ret
;
187 IntEngLeave(&EnterLeaveDest
);
188 IntEngLeave(&EnterLeaveSource
);
194 IntEngAlphaBlend(IN SURFOBJ
*psoDest
,
195 IN SURFOBJ
*psoSource
,
196 IN CLIPOBJ
*ClipRegion
,
197 IN XLATEOBJ
*ColorTranslation
,
199 IN PRECTL SourceRect
,
200 IN BLENDOBJ
*BlendObj
)
204 SURFACE
*psurfSource
;
207 psurfDest
= CONTAINING_RECORD(psoDest
, SURFACE
, SurfObj
);
210 psurfSource
= CONTAINING_RECORD(psoSource
, SURFACE
, SurfObj
);
215 /* Check if there is anything to draw */
216 if (ClipRegion
!= NULL
&&
217 (ClipRegion
->rclBounds
.left
>= ClipRegion
->rclBounds
.right
||
218 ClipRegion
->rclBounds
.top
>= ClipRegion
->rclBounds
.bottom
))
224 /* Call the driver's DrvAlphaBlend if available */
225 if (psurfDest
->flags
& HOOK_ALPHABLEND
)
227 ret
= GDIDEVFUNCS(psoDest
).AlphaBlend(
228 psoDest
, psoSource
, ClipRegion
, ColorTranslation
,
229 DestRect
, SourceRect
, BlendObj
);
234 ret
= EngAlphaBlend(psoDest
, psoSource
, ClipRegion
, ColorTranslation
,
235 DestRect
, SourceRect
, BlendObj
);
246 NtGdiEngAlphaBlend(IN SURFOBJ
*psoDest
,
247 IN SURFOBJ
*psoSource
,
248 IN CLIPOBJ
*ClipRegion
,
249 IN XLATEOBJ
*ColorTranslation
,
250 IN PRECTL upDestRect
,
251 IN PRECTL upSourceRect
,
252 IN BLENDOBJ
*BlendObj
)
259 ProbeForRead(upDestRect
, sizeof(RECTL
), 1);
260 RtlCopyMemory(&DestRect
,upDestRect
, sizeof(RECTL
));
262 ProbeForRead(upSourceRect
, sizeof(RECTL
), 1);
263 RtlCopyMemory(&SourceRect
, upSourceRect
, sizeof(RECTL
));
266 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
268 _SEH2_YIELD(return FALSE
);
272 return EngAlphaBlend(psoDest
, psoSource
, ClipRegion
, ColorTranslation
, &DestRect
, &SourceRect
, BlendObj
);