1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * PURPOSE: GDI EngCopyBits Function 5 * FILE: win32ss/gdi/eng/copybits.c 6 * PROGRAMER: Jason Filby 7 */ 8 9 #include <win32k.h> 10 11 #define NDEBUG 12 #include <debug.h> 13 14 /* 15 * @implemented 16 */ 17 BOOL APIENTRY 18 EngCopyBits( 19 _In_ SURFOBJ *psoDest, 20 _In_ SURFOBJ *psoSource, 21 _In_opt_ CLIPOBJ *Clip, 22 _In_opt_ XLATEOBJ *ColorTranslation, 23 _In_ RECTL *DestRect, 24 _In_ POINTL *SourcePoint) 25 { 26 BOOL ret; 27 BYTE clippingType; 28 RECT_ENUM RectEnum; 29 BOOL EnumMore; 30 BLTINFO BltInfo; 31 SURFACE *psurfDest; 32 SURFACE *psurfSource; 33 RECTL rclDest = *DestRect; 34 POINTL ptlSrc = *SourcePoint; 35 36 ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL); 37 38 psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); 39 psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); 40 41 /* Clip dest rect against source surface size / source point */ 42 if (psoSource->sizlBitmap.cx - ptlSrc.x < rclDest.right - rclDest.left) 43 rclDest.right = rclDest.left + psoSource->sizlBitmap.cx - ptlSrc.x; 44 if (psoSource->sizlBitmap.cy - ptlSrc.y < rclDest.bottom - rclDest.top) 45 rclDest.bottom = rclDest.top + psoSource->sizlBitmap.cy - ptlSrc.y; 46 47 /* Clip dest rect against target surface size */ 48 if (rclDest.right > psoDest->sizlBitmap.cx) 49 rclDest.right = psoDest->sizlBitmap.cx; 50 if (rclDest.bottom > psoDest->sizlBitmap.cy) 51 rclDest.bottom = psoDest->sizlBitmap.cy; 52 if (RECTL_bIsEmptyRect(&rclDest)) return TRUE; 53 DestRect = &rclDest; 54 55 // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead, 56 // mark the copy block function to be DrvCopyBits instead of the 57 // GDI's copy bit function so as to remove clipping from the 58 // driver's responsibility 59 60 // If one of the surfaces isn't managed by the GDI 61 if ((psoDest->iType!=STYPE_BITMAP) || (psoSource->iType!=STYPE_BITMAP)) 62 { 63 // Destination surface is device managed 64 if (psoDest->iType!=STYPE_BITMAP) 65 { 66 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */ 67 if (psurfDest->flags & HOOK_COPYBITS) 68 { 69 ret = GDIDEVFUNCS(psoDest).CopyBits( 70 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); 71 72 goto cleanup; 73 } 74 } 75 76 // Source surface is device managed 77 if (psoSource->iType!=STYPE_BITMAP) 78 { 79 /* FIXME: Eng* functions shouldn't call Drv* functions. ? */ 80 if (psurfSource->flags & HOOK_COPYBITS) 81 { 82 ret = GDIDEVFUNCS(psoSource).CopyBits( 83 psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); 84 85 goto cleanup; 86 } 87 } 88 89 // If CopyBits wasn't hooked, BitBlt must be 90 ret = IntEngBitBlt(psoDest, psoSource, 91 NULL, Clip, ColorTranslation, DestRect, SourcePoint, 92 NULL, NULL, NULL, ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY)); 93 94 goto cleanup; 95 } 96 97 // Determine clipping type 98 if (!Clip) 99 { 100 clippingType = DC_TRIVIAL; 101 } 102 else 103 { 104 clippingType = Clip->iDComplexity; 105 } 106 107 BltInfo.DestSurface = psoDest; 108 BltInfo.SourceSurface = psoSource; 109 BltInfo.PatternSurface = NULL; 110 BltInfo.XlateSourceToDest = ColorTranslation; 111 BltInfo.Rop4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY); 112 113 switch (clippingType) 114 { 115 case DC_TRIVIAL: 116 BltInfo.DestRect = *DestRect; 117 BltInfo.SourcePoint = *SourcePoint; 118 119 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo); 120 break; 121 122 case DC_RECT: 123 // Clip the blt to the clip rectangle 124 RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds); 125 126 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left; 127 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top; 128 129 ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo); 130 break; 131 132 case DC_COMPLEX: 133 134 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0); 135 136 do 137 { 138 EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum); 139 140 if (RectEnum.c > 0) 141 { 142 RECTL* prclEnd = &RectEnum.arcl[RectEnum.c]; 143 RECTL* prcl = &RectEnum.arcl[0]; 144 145 do 146 { 147 RECTL_bIntersectRect(&BltInfo.DestRect, prcl, DestRect); 148 149 BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left; 150 BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top; 151 152 if (!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo)) 153 { 154 ret = FALSE; 155 goto cleanup; 156 } 157 158 prcl++; 159 160 } while (prcl < prclEnd); 161 } 162 163 } while (EnumMore); 164 ret = TRUE; 165 break; 166 167 default: 168 ASSERT(FALSE); 169 ret = FALSE; 170 break; 171 } 172 173 cleanup: 174 return ret; 175 } 176 177 BOOL APIENTRY 178 IntEngCopyBits( 179 SURFOBJ *psoDest, 180 SURFOBJ *psoSource, 181 CLIPOBJ *pco, 182 XLATEOBJ *pxlo, 183 RECTL *prclDest, 184 POINTL *ptlSource) 185 { 186 return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource); 187 } 188 189 190 /* EOF */ 191