Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenalphablend.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * PURPOSE: GDI alpha blending functions 00005 * FILE: subsystems/win32/win32k/eng/alphablend.c 00006 * PROGRAMER: Jason Filby 00007 */ 00008 00009 #include <win32k.h> 00010 00011 #define NDEBUG 00012 #include <debug.h> 00013 00014 00015 /* 00016 * @implemented 00017 */ 00018 BOOL 00019 APIENTRY 00020 EngAlphaBlend(IN SURFOBJ *psoDest, 00021 IN SURFOBJ *psoSource, 00022 IN CLIPOBJ *ClipRegion, 00023 IN XLATEOBJ *ColorTranslation, 00024 IN PRECTL DestRect, 00025 IN PRECTL SourceRect, 00026 IN BLENDOBJ *BlendObj) 00027 { 00028 RECTL InputRect; 00029 RECTL OutputRect; 00030 RECTL ClipRect; 00031 RECTL CombinedRect; 00032 RECTL Rect; 00033 POINTL Translate; 00034 INTENG_ENTER_LEAVE EnterLeaveSource; 00035 INTENG_ENTER_LEAVE EnterLeaveDest; 00036 SURFOBJ* InputObj; 00037 SURFOBJ* OutputObj; 00038 LONG ClippingType; 00039 RECT_ENUM RectEnum; 00040 BOOL EnumMore; 00041 ULONG i; 00042 BOOLEAN Ret; 00043 00044 DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", psoDest, psoSource, ClipRegion, ColorTranslation); 00045 DPRINT(" DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n", 00046 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom, 00047 SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom); 00048 DPRINT(" BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj->BlendFunction.BlendOp, 00049 BlendObj->BlendFunction.BlendFlags, BlendObj->BlendFunction.SourceConstantAlpha, 00050 BlendObj->BlendFunction.AlphaFormat); 00051 00052 /* Validate output */ 00053 OutputRect = *DestRect; 00054 RECTL_vMakeWellOrdered(&OutputRect); 00055 00056 /* Validate input */ 00057 InputRect = *SourceRect; 00058 RECTL_vMakeWellOrdered(&InputRect); 00059 if ( (InputRect.top < 0) || (InputRect.bottom < 0) || 00060 (InputRect.left < 0) || (InputRect.right < 0) || 00061 InputRect.right > psoSource->sizlBitmap.cx || 00062 InputRect.bottom > psoSource->sizlBitmap.cy ) 00063 { 00064 EngSetLastError(ERROR_INVALID_PARAMETER); 00065 return FALSE; 00066 } 00067 00068 if (psoDest == psoSource && 00069 !(OutputRect.left >= SourceRect->right || InputRect.left >= OutputRect.right || 00070 OutputRect.top >= SourceRect->bottom || InputRect.top >= OutputRect.bottom)) 00071 { 00072 DPRINT1("Source and destination rectangles overlap!\n"); 00073 return FALSE; 00074 } 00075 00076 if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER) 00077 { 00078 DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj->BlendFunction.BlendOp); 00079 return FALSE; 00080 } 00081 if (BlendObj->BlendFunction.BlendFlags != 0) 00082 { 00083 DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj->BlendFunction.BlendFlags); 00084 return FALSE; 00085 } 00086 if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0) 00087 { 00088 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj->BlendFunction.AlphaFormat); 00089 return FALSE; 00090 } 00091 00092 /* Check if there is anything to draw */ 00093 if (ClipRegion != NULL && 00094 (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right || 00095 ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom)) 00096 { 00097 /* Nothing to do */ 00098 return TRUE; 00099 } 00100 00101 /* Now call the DIB function */ 00102 if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj)) 00103 { 00104 return FALSE; 00105 } 00106 InputRect.left += Translate.x; 00107 InputRect.right += Translate.x; 00108 InputRect.top += Translate.y; 00109 InputRect.bottom += Translate.y; 00110 00111 if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj)) 00112 { 00113 return FALSE; 00114 } 00115 OutputRect.left += Translate.x; 00116 OutputRect.right += Translate.x; 00117 OutputRect.top += Translate.y; 00118 OutputRect.bottom += Translate.y; 00119 00120 ASSERT(InputRect.left < InputRect.right && InputRect.top < InputRect.bottom); 00121 00122 Ret = FALSE; 00123 ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity; 00124 switch (ClippingType) 00125 { 00126 case DC_TRIVIAL: 00127 Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend( 00128 OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion, ColorTranslation, BlendObj); 00129 break; 00130 00131 case DC_RECT: 00132 ClipRect.left = ClipRegion->rclBounds.left + Translate.x; 00133 ClipRect.right = ClipRegion->rclBounds.right + Translate.x; 00134 ClipRect.top = ClipRegion->rclBounds.top + Translate.y; 00135 ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y; 00136 if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) 00137 { 00138 /* take into acount clipping results when calculating new input rect (scaled to input rect size) */ 00139 Rect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * (InputRect.right - InputRect.left) / (OutputRect.right - OutputRect.left); 00140 Rect.right = InputRect.right + (CombinedRect.right - OutputRect.right) * (InputRect.right - InputRect.left) / (OutputRect.right - OutputRect.left); 00141 Rect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * (InputRect.bottom - InputRect.top) / (OutputRect.bottom - OutputRect.top); 00142 Rect.bottom = InputRect.bottom + (CombinedRect.bottom - OutputRect.bottom) * (InputRect.bottom - InputRect.top) / (OutputRect.bottom - OutputRect.top); 00143 ASSERT(InputRect.left < InputRect.right && InputRect.top < InputRect.bottom); 00144 00145 /* Aplha blend one rect */ 00146 Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend( 00147 OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj); 00148 } 00149 break; 00150 00151 case DC_COMPLEX: 00152 Ret = TRUE; 00153 CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0); 00154 do 00155 { 00156 EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), 00157 (PVOID) &RectEnum); 00158 00159 for (i = 0; i < RectEnum.c; i++) 00160 { 00161 ClipRect.left = RectEnum.arcl[i].left + Translate.x; 00162 ClipRect.right = RectEnum.arcl[i].right + Translate.x; 00163 ClipRect.top = RectEnum.arcl[i].top + Translate.y; 00164 ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y; 00165 if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) 00166 { 00167 /* take into acount clipping results when calculating new input rect (scaled to input rect size) */ 00168 Rect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * (InputRect.right - InputRect.left) / (OutputRect.right - OutputRect.left); 00169 Rect.right = InputRect.right + (CombinedRect.right - OutputRect.right) * (InputRect.right - InputRect.left) / (OutputRect.right - OutputRect.left); 00170 Rect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * (InputRect.bottom - InputRect.top) / (OutputRect.bottom - OutputRect.top); 00171 Rect.bottom = InputRect.bottom + (CombinedRect.bottom - OutputRect.bottom) * (InputRect.bottom - InputRect.top) / (OutputRect.bottom - OutputRect.top); 00172 ASSERT(InputRect.left < InputRect.right && InputRect.top < InputRect.bottom); 00173 00174 /* Alpha blend one rect */ 00175 Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend( 00176 OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj) && Ret; 00177 } 00178 } 00179 } 00180 while (EnumMore); 00181 break; 00182 00183 default: 00184 UNIMPLEMENTED; 00185 ASSERT(FALSE); 00186 break; 00187 } 00188 00189 IntEngLeave(&EnterLeaveDest); 00190 IntEngLeave(&EnterLeaveSource); 00191 00192 return Ret; 00193 } 00194 00195 BOOL APIENTRY 00196 IntEngAlphaBlend(IN SURFOBJ *psoDest, 00197 IN SURFOBJ *psoSource, 00198 IN CLIPOBJ *ClipRegion, 00199 IN XLATEOBJ *ColorTranslation, 00200 IN PRECTL DestRect, 00201 IN PRECTL SourceRect, 00202 IN BLENDOBJ *BlendObj) 00203 { 00204 BOOL ret = FALSE; 00205 SURFACE *psurfDest; 00206 //SURFACE *psurfSource; 00207 00208 ASSERT(psoDest); 00209 psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); 00210 00211 ASSERT(psoSource); 00212 //psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); 00213 00214 ASSERT(DestRect); 00215 ASSERT(SourceRect); 00216 00217 /* Check if there is anything to draw */ 00218 if (ClipRegion != NULL && 00219 (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right || 00220 ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom)) 00221 { 00222 /* Nothing to do */ 00223 return TRUE; 00224 } 00225 00226 /* Call the driver's DrvAlphaBlend if available */ 00227 if (psurfDest->flags & HOOK_ALPHABLEND) 00228 { 00229 ret = GDIDEVFUNCS(psoDest).AlphaBlend( 00230 psoDest, psoSource, ClipRegion, ColorTranslation, 00231 DestRect, SourceRect, BlendObj); 00232 } 00233 00234 if (! ret) 00235 { 00236 ret = EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation, 00237 DestRect, SourceRect, BlendObj); 00238 } 00239 00240 return ret; 00241 } 00242 00243 /* 00244 * @implemented 00245 */ 00246 BOOL 00247 APIENTRY 00248 NtGdiEngAlphaBlend(IN SURFOBJ *psoDest, 00249 IN SURFOBJ *psoSource, 00250 IN CLIPOBJ *ClipRegion, 00251 IN XLATEOBJ *ColorTranslation, 00252 IN PRECTL upDestRect, 00253 IN PRECTL upSourceRect, 00254 IN BLENDOBJ *BlendObj) 00255 { 00256 RECTL DestRect; 00257 RECTL SourceRect; 00258 00259 _SEH2_TRY 00260 { 00261 ProbeForRead(upDestRect, sizeof(RECTL), 1); 00262 RtlCopyMemory(&DestRect,upDestRect, sizeof(RECTL)); 00263 00264 ProbeForRead(upSourceRect, sizeof(RECTL), 1); 00265 RtlCopyMemory(&SourceRect, upSourceRect, sizeof(RECTL)); 00266 00267 } 00268 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00269 { 00270 _SEH2_YIELD(return FALSE); 00271 } 00272 _SEH2_END; 00273 00274 return EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation, &DestRect, &SourceRect, BlendObj); 00275 } 00276 Generated on Fri May 25 2012 04:36:28 for ReactOS by
1.7.6.1
|