1 /* 2 * PROJECT: Win32 subsystem 3 * LICENSE: See COPYING in the top level directory 4 * FILE: win32ss/gdi/dib/dib1bpp.c 5 * PURPOSE: Device Independant Bitmap functions, 1bpp 6 * PROGRAMMERS: Jason Filby 7 */ 8 9 #include <win32k.h> 10 11 #define NDEBUG 12 #include <debug.h> 13 14 VOID 15 DIB_1BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c) 16 { 17 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3); 18 19 if (0 == (c & 0x01)) 20 *addr &= ~MASK1BPP(x); 21 else 22 *addr |= MASK1BPP(x); 23 } 24 25 ULONG 26 DIB_1BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y) 27 { 28 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3); 29 30 return (*addr & MASK1BPP(x) ? 1 : 0); 31 } 32 33 VOID 34 DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c) 35 { 36 while(x1 < x2) 37 { 38 DIB_1BPP_PutPixel(SurfObj, x1, y, c); 39 x1++; 40 } 41 } 42 43 VOID 44 DIB_1BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) 45 { 46 while(y1 < y2) 47 { 48 DIB_1BPP_PutPixel(SurfObj, x, y1, c); 49 y1++; 50 } 51 } 52 53 static 54 void 55 DIB_1BPP_BitBltSrcCopy_From1BPP ( 56 SURFOBJ* DestSurf, 57 SURFOBJ* SourceSurf, 58 XLATEOBJ* pxlo, 59 PRECTL DestRect, 60 POINTL *SourcePoint ) 61 { 62 // The 'window' in this sense is the x-position that corresponds 63 // to the left-edge of the 8-pixel byte we are currently working with. 64 // dwx is current x-window, dwx2 is the 'last' window we need to process. 65 int dwx, dwx2; // Destination window x-position 66 int swx; // Source window y-position 67 68 // Left and right edges of source and dest rectangles 69 int dl = DestRect->left; // dest left 70 int dr = DestRect->right-1; // dest right (inclusive) 71 int sl = SourcePoint->x; // source left 72 int sr = sl + dr - dl; // source right (inclusive) 73 74 // Which direction are we going? 75 int xinc; 76 int yinc; 77 int ySrcDelta, yDstDelta; 78 79 // The following 4 variables are used for the y-sweep 80 int dy; // dest y 81 int dy1; // dest y start 82 int dy2; // dest y end 83 int sy1; // src y start 84 85 int shift; 86 BYTE srcmask, dstmask, xormask; 87 88 // 'd' and 's' are the dest & src buffer pointers that I use on my x-sweep 89 // 'pd' and 'ps' are the dest & src buffer pointers used on the inner y-sweep 90 PBYTE d, pd; // dest ptrs 91 PBYTE s, ps; // src ptrs 92 93 shift = (dl-sl)&7; 94 95 xormask = 0xFF * (BYTE)XLATEOBJ_iXlate(pxlo, 0); 96 97 if ( DestRect->top <= SourcePoint->y ) 98 { 99 // Moving up (scan top -> bottom) 100 dy1 = DestRect->top; 101 dy2 = DestRect->bottom - 1; 102 sy1 = SourcePoint->y; 103 yinc = 1; 104 ySrcDelta = SourceSurf->lDelta; 105 yDstDelta = DestSurf->lDelta; 106 } 107 else 108 { 109 // Moving down (scan bottom -> top) 110 dy1 = DestRect->bottom - 1; 111 dy2 = DestRect->top; 112 sy1 = SourcePoint->y + dy1 - dy2; 113 yinc = -1; 114 ySrcDelta = -SourceSurf->lDelta; 115 yDstDelta = -DestSurf->lDelta; 116 } 117 if ( DestRect->left <= SourcePoint->x ) 118 { 119 // Moving left (scan left->right) 120 dwx = dl&~7; 121 swx = (sl-(dl&7))&~7; 122 dwx2 = dr&~7; 123 xinc = 1; 124 } 125 else 126 { 127 // Moving right (scan right->left) 128 dwx = dr & ~7; 129 swx = (sr - (dr & 7)) & ~7; // (sr - 7) & ~7; // We need the left edge of this block. Thus the -7 130 dwx2 = dl & ~7; 131 xinc = -1; 132 } 133 d = &(((PBYTE)DestSurf->pvScan0)[dy1*DestSurf->lDelta + (dwx>>3)]); 134 s = &(((PBYTE)SourceSurf->pvScan0)[sy1*SourceSurf->lDelta + (swx>>3)]); 135 for ( ;; ) 136 { 137 dy = dy1; 138 pd = d; 139 ps = s; 140 srcmask = 0xff; 141 if ( dwx < dl ) 142 { 143 int diff = dl-dwx; 144 srcmask &= (1<<(8-diff))-1; 145 } 146 if ( dwx+7 > dr ) 147 { 148 int diff = dr-dwx+1; 149 srcmask &= ~((1<<(8-diff))-1); 150 } 151 dstmask = ~srcmask; 152 153 // We unfortunately *must* have 5 different versions of the inner 154 // loop to be certain we don't try to read from memory that is not 155 // needed and may in fact be invalid. 156 if ( !shift ) 157 { 158 for ( ;; ) 159 { 160 *pd = (BYTE)((*pd & dstmask) | ((ps[0]^xormask) & srcmask)); 161 162 // This *must* be here, because we could be going up *or* down... 163 if ( dy == dy2 ) 164 break; 165 dy += yinc; 166 pd += yDstDelta; 167 ps += ySrcDelta; 168 } 169 } 170 else if ( !(0xFF00 & (srcmask<<shift) ) ) // Check if ps[0] not needed... 171 { 172 for ( ;; ) 173 { 174 *pd = (BYTE)((*pd & dstmask) 175 | ( ( (ps[1]^xormask) >> shift ) & srcmask )); 176 177 // This *must* be here, because we could be going up *or* down... 178 if ( dy == dy2 ) 179 break; 180 dy += yinc; 181 pd += yDstDelta; 182 ps += ySrcDelta; 183 } 184 } 185 else if ( !(0xFF & (srcmask<<shift) ) ) // Check if ps[1] not needed... 186 { 187 for ( ;; ) 188 { 189 *pd = (*pd & dstmask) 190 | ( ( (ps[0]^xormask) << ( 8 - shift ) ) & srcmask ); 191 192 // This *must* be here, because we could be going up *or* down... 193 if ( dy == dy2 ) 194 break; 195 dy += yinc; 196 pd += yDstDelta; 197 ps += ySrcDelta; 198 } 199 } 200 else // Both ps[0] and ps[1] are needed 201 { 202 for ( ;; ) 203 { 204 *pd = (*pd & dstmask) 205 | ( ( ( ((ps[1]^xormask))|((ps[0]^xormask)<<8) ) >> shift ) & srcmask ); 206 207 // This *must* be here, because we could be going up *or* down... 208 if ( dy == dy2 ) 209 break; 210 dy += yinc; 211 pd += yDstDelta; 212 ps += ySrcDelta; 213 } 214 } 215 216 // This *must* be here, because we could be going right *or* left... 217 if ( dwx == dwx2 ) 218 break; 219 d += xinc; 220 s += xinc; 221 dwx += xinc<<3; 222 swx += xinc<<3; 223 } 224 } 225 226 BOOLEAN 227 DIB_1BPP_BitBltSrcCopy(PBLTINFO BltInfo) 228 { 229 ULONG Color; 230 LONG i, j, sx, sy = BltInfo->SourcePoint.y; 231 232 switch ( BltInfo->SourceSurface->iBitmapFormat ) 233 { 234 case BMF_1BPP: 235 DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo->DestSurface, BltInfo->SourceSurface, BltInfo->XlateSourceToDest, &BltInfo->DestRect, &BltInfo->SourcePoint ); 236 break; 237 238 case BMF_4BPP: 239 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 240 { 241 sx = BltInfo->SourcePoint.x; 242 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 243 { 244 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy)); 245 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color); 246 sx++; 247 } 248 sy++; 249 } 250 break; 251 252 case BMF_8BPP: 253 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 254 { 255 sx = BltInfo->SourcePoint.x; 256 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 257 { 258 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_8BPP_GetPixel(BltInfo->SourceSurface, sx, sy)); 259 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color); 260 sx++; 261 } 262 sy++; 263 } 264 break; 265 266 case BMF_16BPP: 267 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 268 { 269 sx = BltInfo->SourcePoint.x; 270 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 271 { 272 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_16BPP_GetPixel(BltInfo->SourceSurface, sx, sy)); 273 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color); 274 sx++; 275 } 276 sy++; 277 } 278 break; 279 280 case BMF_24BPP: 281 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 282 { 283 sx = BltInfo->SourcePoint.x; 284 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 285 { 286 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy)); 287 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color); 288 sx++; 289 } 290 sy++; 291 } 292 break; 293 294 case BMF_32BPP: 295 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 296 { 297 sx = BltInfo->SourcePoint.x; 298 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 299 { 300 Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_32BPP_GetPixel(BltInfo->SourceSurface, sx, sy)); 301 DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color); 302 sx++; 303 } 304 sy++; 305 } 306 break; 307 308 default: 309 DbgPrint("DIB_1BPP_BitBlt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat)); 310 return FALSE; 311 } 312 313 return TRUE; 314 } 315 316 #ifndef _USE_DIBLIB_ 317 BOOLEAN 318 DIB_1BPP_BitBlt(PBLTINFO BltInfo) 319 { 320 LONG DestX, DestY; 321 LONG SourceX, SourceY; 322 LONG PatternY = 0; 323 ULONG Dest, Source = 0, Pattern = 0; 324 ULONG Index; 325 BOOLEAN UsesSource; 326 BOOLEAN UsesPattern; 327 PULONG DestBits; 328 LONG RoundedRight; 329 330 UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4); 331 UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4); 332 333 RoundedRight = BltInfo->DestRect.right - 334 ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 31); 335 SourceY = BltInfo->SourcePoint.y; 336 337 if (UsesPattern) 338 { 339 if (BltInfo->PatternSurface) 340 { 341 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) % 342 BltInfo->PatternSurface->sizlBitmap.cy; 343 } 344 else 345 { 346 /* FIXME: Shouldn't it be expanded? */ 347 if (BltInfo->Brush) 348 Pattern = BltInfo->Brush->iSolidColor; 349 } 350 } 351 352 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++) 353 { 354 DestX = BltInfo->DestRect.left; 355 SourceX = BltInfo->SourcePoint.x; 356 DestBits = (PULONG)( 357 (PBYTE)BltInfo->DestSurface->pvScan0 + 358 (BltInfo->DestRect.left >> 3) + 359 DestY * BltInfo->DestSurface->lDelta); 360 361 if (DestX & 31) 362 { 363 #if 0 364 /* FIXME: This case is completely untested!!! */ 365 366 Dest = *((PBYTE)DestBits); 367 NoBits = 31 - (DestX & 31); 368 369 if (UsesSource) 370 { 371 Source = 0; 372 /* FIXME: This is incorrect! */ 373 for (Index = 31 - NoBits; Index >= 0; Index++) 374 Source |= (DIB_GetSource(SourceSurf, SourceX + Index, SourceY, ColorTranslation) << (31 - Index)); 375 } 376 377 if (BltInfo->PatternSurface) 378 { 379 Pattern = 0; 380 for (k = 31 - NoBits; k >= 0; k++) 381 Pattern |= (DIB_GetSourceIndex(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY) << (31 - k)); 382 } 383 384 Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern); 385 Dest &= ~((1 << (31 - NoBits)) - 1); 386 Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1); 387 388 *DestBits = Dest; 389 390 DestX += NoBits; 391 SourceX += NoBits; 392 #endif 393 } 394 395 for (; DestX < RoundedRight; DestX += 32, DestBits++, SourceX += 32) 396 { 397 Dest = *DestBits; 398 399 if (UsesSource) 400 { 401 Source = 0; 402 for (Index = 0; Index < 8; Index++) 403 { 404 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index, SourceY, BltInfo->XlateSourceToDest) << (7 - Index); 405 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 8, SourceY, BltInfo->XlateSourceToDest) << (8 + (7 - Index)); 406 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 16, SourceY, BltInfo->XlateSourceToDest) << (16 + (7 - Index)); 407 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + Index + 24, SourceY, BltInfo->XlateSourceToDest) << (24 + (7 - Index)); 408 } 409 } 410 411 if (BltInfo->PatternSurface) 412 { 413 Pattern = 0; 414 for (Index = 0; Index < 8; Index++) 415 { 416 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (7 - Index); 417 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 8) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (8 + (7 - Index)); 418 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 16) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (16 + (7 - Index)); 419 Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + Index + 24) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << (24 + (7 - Index)); 420 } 421 } 422 423 *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern); 424 } 425 426 if (DestX < BltInfo->DestRect.right) 427 { 428 for (; DestX < BltInfo->DestRect.right; DestX++, SourceX++) 429 { 430 Dest = DIB_1BPP_GetPixel(BltInfo->DestSurface, DestX, DestY); 431 432 if (UsesSource) 433 { 434 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest); 435 } 436 437 if (BltInfo->PatternSurface) 438 { 439 Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY); 440 } 441 442 DIB_1BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF); 443 } 444 } 445 446 SourceY++; 447 if (BltInfo->PatternSurface) 448 { 449 PatternY++; 450 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy; 451 } 452 } 453 454 return TRUE; 455 } 456 457 /* BitBlt Optimize */ 458 BOOLEAN 459 DIB_1BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color) 460 { 461 LONG DestY; 462 463 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++) 464 { 465 DIB_1BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color); 466 } 467 return TRUE; 468 } 469 #endif // !_USE_DIBLIB_ 470 471 BOOLEAN 472 DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 473 RECTL* DestRect, RECTL *SourceRect, 474 XLATEOBJ *ColorTranslation, ULONG iTransColor) 475 { 476 return FALSE; 477 } 478 479 /* EOF */ 480