1 /* 2 * PROJECT: ReactOS Win32k subsystem 3 * LICENSE: See COPYING in the top level directory 4 * FILE: win32ss/gdi/dib/stretchblt.c 5 * PURPOSE: StretchBlt implementation suitable for all bit depths 6 * PROGRAMMERS: Magnus Olsen 7 * Evgeniy Boltik 8 * Gregor Schneider 9 */ 10 11 #include <win32k.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *MaskSurf, 17 SURFOBJ *PatternSurface, 18 RECTL *DestRect, RECTL *SourceRect, 19 POINTL *MaskOrigin, BRUSHOBJ *Brush, 20 POINTL *BrushOrigin, XLATEOBJ *ColorTranslation, 21 ROP4 ROP) 22 { 23 LONG sx = 0; 24 LONG sy = 0; 25 LONG DesX; 26 LONG DesY; 27 28 LONG DstHeight; 29 LONG DstWidth; 30 LONG SrcHeight; 31 LONG SrcWidth; 32 LONG MaskCy; 33 LONG SourceCy; 34 35 ULONG Color; 36 ULONG Dest, Source = 0, Pattern = 0; 37 ULONG xxBPPMask; 38 BOOLEAN CanDraw; 39 40 PFN_DIB_GetPixel fnSource_GetPixel = NULL; 41 PFN_DIB_GetPixel fnDest_GetPixel = NULL; 42 PFN_DIB_PutPixel fnDest_PutPixel = NULL; 43 PFN_DIB_GetPixel fnPattern_GetPixel = NULL; 44 PFN_DIB_GetPixel fnMask_GetPixel = NULL; 45 46 LONG PatternX = 0, PatternY = 0; 47 48 BOOL UsesSource = ROP4_USES_SOURCE(ROP); 49 BOOL UsesPattern = ROP4_USES_PATTERN(ROP); 50 51 ASSERT(IS_VALID_ROP4(ROP)); 52 53 fnDest_GetPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_GetPixel; 54 fnDest_PutPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_PutPixel; 55 56 DPRINT("Dest BPP: %u, dstRect: (%d,%d)-(%d,%d)\n", 57 BitsPerFormat(DestSurf->iBitmapFormat), DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); 58 59 if (UsesSource) 60 { 61 SourceCy = SourceSurf->sizlBitmap.cy; 62 fnSource_GetPixel = DibFunctionsForBitmapFormat[SourceSurf->iBitmapFormat].DIB_GetPixel; 63 DPRINT("Source BPP: %u, srcRect: (%d,%d)-(%d,%d)\n", 64 BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom); 65 } 66 67 if (MaskSurf) 68 { 69 fnMask_GetPixel = DibFunctionsForBitmapFormat[MaskSurf->iBitmapFormat].DIB_GetPixel; 70 MaskCy = MaskSurf->sizlBitmap.cy; 71 } 72 73 DstHeight = DestRect->bottom - DestRect->top; 74 DstWidth = DestRect->right - DestRect->left; 75 SrcHeight = SourceRect->bottom - SourceRect->top; 76 SrcWidth = SourceRect->right - SourceRect->left; 77 78 /* FIXME: MaskOrigin? */ 79 80 switch(DestSurf->iBitmapFormat) 81 { 82 case BMF_1BPP: xxBPPMask = 0x1; break; 83 case BMF_4BPP: xxBPPMask = 0xF; break; 84 case BMF_8BPP: xxBPPMask = 0xFF; break; 85 case BMF_16BPP: xxBPPMask = 0xFFFF; break; 86 case BMF_24BPP: xxBPPMask = 0xFFFFFF; break; 87 default: 88 xxBPPMask = 0xFFFFFFFF; 89 } 90 91 if (UsesPattern) 92 { 93 if (PatternSurface) 94 { 95 PatternY = (DestRect->top - BrushOrigin->y) % PatternSurface->sizlBitmap.cy; 96 if (PatternY < 0) 97 { 98 PatternY += PatternSurface->sizlBitmap.cy; 99 } 100 fnPattern_GetPixel = DibFunctionsForBitmapFormat[PatternSurface->iBitmapFormat].DIB_GetPixel; 101 } 102 else 103 { 104 if (Brush) 105 Pattern = Brush->iSolidColor; 106 } 107 } 108 109 110 for (DesY = DestRect->top; DesY < DestRect->bottom; DesY++) 111 { 112 if (PatternSurface) 113 { 114 PatternX = (DestRect->left - BrushOrigin->x) % PatternSurface->sizlBitmap.cx; 115 if (PatternX < 0) 116 { 117 PatternX += PatternSurface->sizlBitmap.cx; 118 } 119 } 120 if (UsesSource) 121 sy = SourceRect->top+(DesY - DestRect->top) * SrcHeight / DstHeight; 122 123 for (DesX = DestRect->left; DesX < DestRect->right; DesX++) 124 { 125 CanDraw = TRUE; 126 127 if (fnMask_GetPixel) 128 { 129 sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth; 130 if (sx < 0 || sy < 0 || 131 MaskSurf->sizlBitmap.cx < sx || MaskCy < sy || 132 fnMask_GetPixel(MaskSurf, sx, sy) != 0) 133 { 134 CanDraw = FALSE; 135 } 136 } 137 138 if (UsesSource && CanDraw) 139 { 140 sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth; 141 if (sx >= 0 && sy >= 0 && 142 SourceSurf->sizlBitmap.cx > sx && SourceCy > sy) 143 { 144 Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy)); 145 } 146 else 147 { 148 Source = 0; 149 CanDraw = ((ROP & 0xFF) != R3_OPINDEX_SRCCOPY); 150 } 151 } 152 153 if (CanDraw) 154 { 155 if (UsesPattern && PatternSurface) 156 { 157 Pattern = fnPattern_GetPixel(PatternSurface, PatternX, PatternY); 158 PatternX++; 159 PatternX %= PatternSurface->sizlBitmap.cx; 160 } 161 162 Dest = fnDest_GetPixel(DestSurf, DesX, DesY); 163 Color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask; 164 165 fnDest_PutPixel(DestSurf, DesX, DesY, Color); 166 } 167 } 168 169 if (PatternSurface) 170 { 171 PatternY++; 172 PatternY %= PatternSurface->sizlBitmap.cy; 173 } 174 } 175 176 return TRUE; 177 } 178 179 /* EOF */ 180