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

stretchblt.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:        See COPYING in the top level directory
00003  * PROJECT:          ReactOS Win32k subsystem
00004  * PURPOSE:          GDI stretch blt functions
00005  * FILE:             subsystems/win32/win32k/eng/stretchblt.c
00006  * PROGRAMER:        Jason Filby
00007  */
00008 
00009 #include <win32k.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
00015                                             SURFOBJ* InputObj,
00016                                             SURFOBJ* Mask,
00017                                             XLATEOBJ* ColorTranslation,
00018                                             RECTL* OutputRect,
00019                                             RECTL* InputRect,
00020                                             POINTL* MaskOrigin,
00021                                             BRUSHOBJ* pbo,
00022                                             POINTL* BrushOrigin,
00023                                             ROP4 Rop4);
00024 
00025 static BOOLEAN APIENTRY
00026 CallDibStretchBlt(SURFOBJ* psoDest,
00027                   SURFOBJ* psoSource,
00028                   SURFOBJ* Mask,
00029                   XLATEOBJ* ColorTranslation,
00030                   RECTL* OutputRect,
00031                   RECTL* InputRect,
00032                   POINTL* MaskOrigin,
00033                   BRUSHOBJ* pbo,
00034                   POINTL* BrushOrigin,
00035                   ROP4 Rop4)
00036 {
00037     POINTL RealBrushOrigin;
00038     SURFOBJ* psoPattern;
00039     BOOL bResult;
00040 
00041     if (BrushOrigin == NULL)
00042     {
00043         RealBrushOrigin.x = RealBrushOrigin.y = 0;
00044     }
00045     else
00046     {
00047         RealBrushOrigin = *BrushOrigin;
00048     }
00049 
00050     /* Pattern brush */
00051     if (ROP4_USES_PATTERN(Rop4) && pbo && pbo->iSolidColor == 0xFFFFFFFF)
00052     {
00053         psoPattern = BRUSHOBJ_psoPattern(pbo);
00054 
00055         if (!psoPattern) return FALSE;
00056     }
00057     else
00058     {
00059         psoPattern = NULL;
00060     }
00061 
00062     bResult = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt(
00063                psoDest, psoSource, Mask, psoPattern,
00064                OutputRect, InputRect, MaskOrigin, pbo, &RealBrushOrigin,
00065                ColorTranslation, Rop4);
00066 
00067     return bResult;
00068 }
00069 
00070 
00071 
00072 /*
00073  * @implemented
00074  */
00075 BOOL
00076 APIENTRY
00077 EngStretchBltROP(
00078     IN SURFOBJ  *psoDest,
00079     IN SURFOBJ  *psoSource,
00080     IN SURFOBJ  *Mask,
00081     IN CLIPOBJ  *ClipRegion,
00082     IN XLATEOBJ  *ColorTranslation,
00083     IN COLORADJUSTMENT  *pca,
00084     IN POINTL  *BrushOrigin,
00085     IN RECTL  *prclDest,
00086     IN RECTL  *prclSrc,
00087     IN POINTL  *MaskOrigin,
00088     IN ULONG  Mode,
00089     IN BRUSHOBJ *pbo,
00090     IN ROP4 Rop4)
00091 {
00092     RECTL              InputRect;
00093     RECTL              OutputRect;
00094     POINTL             Translate;
00095     INTENG_ENTER_LEAVE EnterLeaveSource;
00096     INTENG_ENTER_LEAVE EnterLeaveDest;
00097     SURFOBJ*           psoInput;
00098     SURFOBJ*           psoOutput;
00099     PSTRETCHRECTFUNC   BltRectFunc;
00100     BOOLEAN            Ret = TRUE;
00101     POINTL             AdjustedBrushOrigin;
00102     BOOL               UsesSource = ROP4_USES_SOURCE(Rop4);
00103 
00104     BYTE               clippingType;
00105     RECTL              ClipRect;
00106     RECT_ENUM          RectEnum;
00107     BOOL               EnumMore;
00108     ULONG              Direction;
00109     RECTL              CombinedRect;
00110     RECTL              InputToCombinedRect;
00111     unsigned           i;
00112 
00113     LONG DstHeight;
00114     LONG DstWidth;
00115     LONG SrcHeight;
00116     LONG SrcWidth;
00117 
00118     if (Rop4 == ROP4_NOOP)
00119     {
00120         /* Copy destination onto itself: nop */
00121         return TRUE;
00122     }
00123 
00124 
00125     /* Determine clipping type */
00126     if (ClipRegion == (CLIPOBJ *) NULL)
00127     {
00128         clippingType = DC_TRIVIAL;
00129     }
00130     else
00131     {
00132         clippingType = ClipRegion->iDComplexity;
00133     }
00134 
00135     OutputRect = *prclDest;
00136     if (OutputRect.right < OutputRect.left)
00137     {
00138         OutputRect.left = prclDest->right;
00139         OutputRect.right = prclDest->left;
00140     }
00141     if (OutputRect.bottom < OutputRect.top)
00142     {
00143         OutputRect.top = prclDest->bottom;
00144         OutputRect.bottom = prclDest->top;
00145     }
00146 
00147     if (UsesSource)
00148     {
00149         if (NULL == prclSrc)
00150         {
00151             return FALSE;
00152         }
00153         InputRect = *prclSrc;
00154 
00155         if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
00156                           &Translate, &psoInput))
00157         {
00158             return FALSE;
00159         }
00160 
00161         InputRect.left += Translate.x;
00162         InputRect.right += Translate.x;
00163         InputRect.top += Translate.y;
00164         InputRect.bottom += Translate.y;
00165     }
00166     else
00167     {
00168         InputRect.left = 0;
00169         InputRect.right = OutputRect.right - OutputRect.left;
00170         InputRect.top = 0;
00171         InputRect.bottom = OutputRect.bottom - OutputRect.top;
00172     }
00173 
00174     if (NULL != ClipRegion)
00175     {
00176         if (OutputRect.left < ClipRegion->rclBounds.left)
00177         {
00178             InputRect.left += ClipRegion->rclBounds.left - OutputRect.left;
00179             OutputRect.left = ClipRegion->rclBounds.left;
00180         }
00181         if (ClipRegion->rclBounds.right < OutputRect.right)
00182         {
00183             InputRect.right -= OutputRect.right - ClipRegion->rclBounds.right;
00184             OutputRect.right = ClipRegion->rclBounds.right;
00185         }
00186         if (OutputRect.top < ClipRegion->rclBounds.top)
00187         {
00188             InputRect.top += ClipRegion->rclBounds.top - OutputRect.top;
00189             OutputRect.top = ClipRegion->rclBounds.top;
00190         }
00191         if (ClipRegion->rclBounds.bottom < OutputRect.bottom)
00192         {
00193             InputRect.bottom -=  OutputRect.bottom - ClipRegion->rclBounds.bottom;
00194             OutputRect.bottom = ClipRegion->rclBounds.bottom;
00195         }
00196     }
00197 
00198     /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
00199        nothing to do */
00200     if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
00201     {
00202         if (UsesSource)
00203         {
00204             IntEngLeave(&EnterLeaveSource);
00205         }
00206         return TRUE;
00207     }
00208 
00209     if (! IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &psoOutput))
00210     {
00211         if (UsesSource)
00212         {
00213             IntEngLeave(&EnterLeaveSource);
00214         }
00215         return FALSE;
00216     }
00217 
00218     OutputRect.left += Translate.x;
00219     OutputRect.right += Translate.x;
00220     OutputRect.top += Translate.y;
00221     OutputRect.bottom += Translate.y;
00222 
00223     if (BrushOrigin)
00224     {
00225         AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
00226         AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
00227     }
00228     else
00229     {
00230         AdjustedBrushOrigin = Translate;
00231     }
00232 
00233     BltRectFunc = CallDibStretchBlt;
00234 
00235     DstHeight = OutputRect.bottom - OutputRect.top;
00236     DstWidth = OutputRect.right - OutputRect.left;
00237     SrcHeight = InputRect.bottom - InputRect.top;
00238     SrcWidth = InputRect.right - InputRect.left;
00239     switch (clippingType)
00240     {
00241         case DC_TRIVIAL:
00242             Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
00243                          ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
00244                          pbo, &AdjustedBrushOrigin, Rop4);
00245             break;
00246         case DC_RECT:
00247             // Clip the blt to the clip rectangle
00248             ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
00249             ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
00250             ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
00251             ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
00252             if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
00253             {
00254                 InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
00255                 InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
00256                 InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
00257                 InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
00258                 Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
00259                            ColorTranslation,
00260                            &CombinedRect,
00261                            &InputToCombinedRect,
00262                            MaskOrigin,
00263                            pbo,
00264                            &AdjustedBrushOrigin,
00265                            Rop4);
00266             }
00267             break;
00268         case DC_COMPLEX:
00269             if (psoOutput == psoInput)
00270             {
00271                 if (OutputRect.top < InputRect.top)
00272                 {
00273                     Direction = OutputRect.left < InputRect.left ?
00274                                 CD_RIGHTDOWN : CD_LEFTDOWN;
00275                 }
00276                 else
00277                 {
00278                     Direction = OutputRect.left < InputRect.left ?
00279                                 CD_RIGHTUP : CD_LEFTUP;
00280                 }
00281             }
00282             else
00283             {
00284                 Direction = CD_ANY;
00285             }
00286             CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
00287             do
00288             {
00289                 EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
00290                                          (PVOID) &RectEnum);
00291                 for (i = 0; i < RectEnum.c; i++)
00292                 {
00293                     ClipRect.left = RectEnum.arcl[i].left + Translate.x;
00294                     ClipRect.right = RectEnum.arcl[i].right + Translate.x;
00295                     ClipRect.top = RectEnum.arcl[i].top + Translate.y;
00296                     ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
00297                     if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
00298                     {
00299                         InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
00300                         InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
00301                         InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
00302                         InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
00303                         Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
00304                            ColorTranslation,
00305                            &CombinedRect,
00306                            &InputToCombinedRect,
00307                            MaskOrigin,
00308                            pbo,
00309                            &AdjustedBrushOrigin,
00310                            Rop4);
00311                     }
00312                 }
00313             }
00314             while (EnumMore);
00315             break;
00316     }
00317 
00318     IntEngLeave(&EnterLeaveDest);
00319     if (UsesSource)
00320     {
00321         IntEngLeave(&EnterLeaveSource);
00322     }
00323 
00324     return Ret;
00325 }
00326 
00327 /*
00328  * @implemented
00329  */
00330 BOOL
00331 APIENTRY
00332 EngStretchBlt(
00333     IN SURFOBJ  *psoDest,
00334     IN SURFOBJ  *psoSource,
00335     IN SURFOBJ  *Mask,
00336     IN CLIPOBJ  *ClipRegion,
00337     IN XLATEOBJ  *ColorTranslation,
00338     IN COLORADJUSTMENT  *pca,
00339     IN POINTL  *BrushOrigin,
00340     IN RECTL  *prclDest,
00341     IN RECTL  *prclSrc,
00342     IN POINTL  *MaskOrigin,
00343     IN ULONG  Mode)
00344 {
00345     return EngStretchBltROP(
00346         psoDest,
00347         psoSource,
00348         Mask,
00349         ClipRegion,
00350         ColorTranslation,
00351         pca,
00352         BrushOrigin,
00353         prclDest,
00354         prclSrc,
00355         MaskOrigin,
00356         Mode,
00357         NULL,
00358         ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
00359 }
00360 
00361 BOOL APIENTRY
00362 IntEngStretchBlt(SURFOBJ *psoDest,
00363                  SURFOBJ *psoSource,
00364                  SURFOBJ *MaskSurf,
00365                  CLIPOBJ *ClipRegion,
00366                  XLATEOBJ *ColorTranslation,
00367                  RECTL *DestRect,
00368                  RECTL *SourceRect,
00369                  POINTL *pMaskOrigin,
00370                  BRUSHOBJ *pbo,
00371                  POINTL *BrushOrigin,
00372                  DWORD Rop4)
00373 {
00374     BOOLEAN ret;
00375     COLORADJUSTMENT ca;
00376     POINTL MaskOrigin = {0, 0};
00377     SURFACE *psurfDest;
00378     //SURFACE *psurfSource = NULL;
00379     RECTL InputClippedRect;
00380     RECTL InputRect;
00381     RECTL OutputRect;
00382     BOOL UsesSource = ROP4_USES_SOURCE(Rop4);
00383     LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
00384 
00385     ASSERT(psoDest);
00386     psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
00387     ASSERT(psurfDest);
00388     ASSERT(DestRect);
00389 
00390     /* Sanity check */
00391     ASSERT(IS_VALID_ROP4(Rop4));
00392 
00393     /* Check if source and dest size are equal */
00394     if (((DestRect->right - DestRect->left) == (SourceRect->right - SourceRect->left)) &&
00395         ((DestRect->bottom - DestRect->top) == (SourceRect->bottom - SourceRect->top)))
00396     {
00397         /* Pass the request to IntEngBitBlt */
00398         return IntEngBitBlt(psoDest,
00399                             psoSource,
00400                             MaskSurf,
00401                             ClipRegion,
00402                             ColorTranslation,
00403                             DestRect,
00404                             (PPOINTL)SourceRect,
00405                             pMaskOrigin,
00406                             pbo,
00407                             BrushOrigin,
00408                             Rop4);
00409     }
00410 
00411     InputClippedRect = *DestRect;
00412     if (InputClippedRect.right < InputClippedRect.left)
00413     {
00414         InputClippedRect.left = DestRect->right;
00415         InputClippedRect.right = DestRect->left;
00416     }
00417     if (InputClippedRect.bottom < InputClippedRect.top)
00418     {
00419         InputClippedRect.top = DestRect->bottom;
00420         InputClippedRect.bottom = DestRect->top;
00421     }
00422 
00423     if (UsesSource)
00424     {
00425         if (NULL == SourceRect || NULL == psoSource)
00426         {
00427             return FALSE;
00428         }
00429         InputRect = *SourceRect;
00430 
00431         if (InputRect.right < InputRect.left ||
00432                 InputRect.bottom < InputRect.top)
00433         {
00434             /* Everything clipped away, nothing to do */
00435             return TRUE;
00436         }
00437     }
00438 
00439     if (ClipRegion)
00440     {
00441         if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect,
00442                                &ClipRegion->rclBounds))
00443         {
00444             return TRUE;
00445         }
00446         /* Update source rect */
00447         InputClWidth = InputClippedRect.right - InputClippedRect.left;
00448         InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
00449         InputWidth = InputRect.right - InputRect.left;
00450         InputHeight = InputRect.bottom - InputRect.top;
00451 
00452         InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) / InputClWidth;
00453         InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) / InputClWidth;
00454         InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) / InputClHeight;
00455         InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom)) / InputClHeight;
00456     }
00457     else
00458     {
00459         OutputRect = InputClippedRect;
00460     }
00461 
00462     if (pMaskOrigin != NULL)
00463     {
00464         MaskOrigin.x = pMaskOrigin->x;
00465         MaskOrigin.y = pMaskOrigin->y;
00466     }
00467 
00468     /* No success yet */
00469     ret = FALSE;
00470 
00471     if (UsesSource)
00472     {
00473         //psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
00474     }
00475 
00476     /* Prepare color adjustment */
00477 
00478     /* Call the driver's DrvStretchBlt if available */
00479     if (psurfDest->flags & HOOK_STRETCHBLTROP)
00480     {
00481         /* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
00482         ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest,
00483                                                  (UsesSource) ? psoSource : NULL,
00484                                                  MaskSurf,
00485                                                  ClipRegion,
00486                                                  ColorTranslation,
00487                                                  &ca, BrushOrigin,
00488                                                  &OutputRect,
00489                                                  &InputRect,
00490                                                  &MaskOrigin,
00491                                                  COLORONCOLOR,
00492                                                  pbo,
00493                                                  Rop4);
00494     }
00495 
00496     if (! ret)
00497     {
00498         ret = EngStretchBltROP(psoDest,
00499                                (UsesSource) ? psoSource : NULL,
00500                                MaskSurf,
00501                                ClipRegion,
00502                                ColorTranslation,
00503                                &ca,
00504                                BrushOrigin,
00505                                &OutputRect,
00506                                &InputRect,
00507                                &MaskOrigin,
00508                                COLORONCOLOR,
00509                                pbo,
00510                                Rop4);
00511     }
00512 
00513     return ret;
00514 }
00515 
00516 BOOL
00517 APIENTRY
00518 NtGdiEngStretchBlt(
00519     IN SURFOBJ  *psoDest,
00520     IN SURFOBJ  *psoSource,
00521     IN SURFOBJ  *Mask,
00522     IN CLIPOBJ  *ClipRegion,
00523     IN XLATEOBJ  *ColorTranslation,
00524     IN COLORADJUSTMENT  *pca,
00525     IN POINTL  *BrushOrigin,
00526     IN RECTL  *prclDest,
00527     IN RECTL  *prclSrc,
00528     IN POINTL  *MaskOrigin,
00529     IN ULONG  Mode)
00530 {
00531     COLORADJUSTMENT  ca;
00532     POINTL  lBrushOrigin;
00533     RECTL rclDest;
00534     RECTL rclSrc;
00535     POINTL lMaskOrigin;
00536 
00537     _SEH2_TRY
00538     {
00539         ProbeForRead(pca, sizeof(COLORADJUSTMENT), 1);
00540         RtlCopyMemory(&ca,pca, sizeof(COLORADJUSTMENT));
00541 
00542         ProbeForRead(BrushOrigin, sizeof(POINTL), 1);
00543         RtlCopyMemory(&lBrushOrigin, BrushOrigin, sizeof(POINTL));
00544 
00545         ProbeForRead(prclDest, sizeof(RECTL), 1);
00546         RtlCopyMemory(&rclDest, prclDest, sizeof(RECTL));
00547 
00548         ProbeForRead(prclSrc, sizeof(RECTL), 1);
00549         RtlCopyMemory(&rclSrc, prclSrc, sizeof(RECTL));
00550 
00551         ProbeForRead(MaskOrigin, sizeof(POINTL), 1);
00552         RtlCopyMemory(&lMaskOrigin, MaskOrigin, sizeof(POINTL));
00553 
00554     }
00555     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00556     {
00557         _SEH2_YIELD(return FALSE);
00558     }
00559     _SEH2_END;
00560 
00561     return EngStretchBlt(psoDest, psoSource, Mask, ClipRegion, ColorTranslation, &ca, &lBrushOrigin, &rclDest, &rclSrc, &lMaskOrigin, Mode);
00562 }
00563 
00564 /* EOF */

Generated on Sat May 26 2012 04:36:59 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.