ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

alphablend.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.