1 /* 2 * PROJECT: Win32 subsystem 3 * LICENSE: See COPYING in the top level directory 4 * FILE: win32ss/gdi/dib/dib8bpp.c 5 * PURPOSE: Device Independant Bitmap functions, 8bpp 6 * PROGRAMMERS: Jason Filby 7 * Thomas Bluemel 8 * Gregor Anich 9 * Doug Lyons 10 */ 11 12 #include <win32k.h> 13 14 #define NDEBUG 15 #include <debug.h> 16 17 #define DEC_OR_INC(var, decTrue, amount) \ 18 ((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount))) 19 20 VOID 21 DIB_8BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c) 22 { 23 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x; 24 25 *byteaddr = (BYTE)c; 26 } 27 28 ULONG 29 DIB_8BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y) 30 { 31 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x; 32 33 return (ULONG)(*byteaddr); 34 } 35 36 VOID 37 DIB_8BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c) 38 { 39 memset((PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x1, (BYTE) c, x2 - x1); 40 } 41 42 VOID 43 DIB_8BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) 44 { 45 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta; 46 PBYTE addr = byteaddr + x; 47 LONG lDelta = SurfObj->lDelta; 48 49 byteaddr = addr; 50 while(y1++ < y2) 51 { 52 *addr = (BYTE)c; 53 54 addr += lDelta; 55 } 56 } 57 58 BOOLEAN 59 DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo) 60 { 61 LONG i, j, sx, sy, xColor, f1; 62 PBYTE SourceBits, DestBits, SourceLine, DestLine; 63 PBYTE SourceBits_4BPP, SourceLine_4BPP; 64 BOOLEAN bTopToBottom, bLeftToRight; 65 66 DPRINT("DIB_8BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n", 67 BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy, 68 BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy, 69 BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom); 70 71 /* Get back left to right flip here */ 72 bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right); 73 74 /* Check for top to bottom flip needed. */ 75 bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom; 76 77 DPRINT("bTopToBottom is '%d' and bLeftToRight is '%d'.\n", bTopToBottom, bLeftToRight); 78 79 /* Make WellOrdered by making top < bottom and left < right */ 80 RECTL_vMakeWellOrdered(&BltInfo->DestRect); 81 82 DPRINT("BPP is '%d' & BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n", 83 BltInfo->SourceSurface->iBitmapFormat, BltInfo->SourcePoint.x, BltInfo->SourcePoint.y); 84 85 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left; 86 87 switch(BltInfo->SourceSurface->iBitmapFormat) 88 { 89 case BMF_1BPP: 90 DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n", 91 BltInfo->DestRect.right - BltInfo->DestRect.left); 92 93 sx = BltInfo->SourcePoint.x; 94 95 /* This sets sy to the top line */ 96 sy = BltInfo->SourcePoint.y; 97 98 if (bTopToBottom) 99 { 100 /* This sets sy to the bottom line */ 101 sy += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1; 102 } 103 104 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 105 { 106 sx = BltInfo->SourcePoint.x; 107 108 if (bLeftToRight) 109 { 110 /* This sets the sx to the rightmost pixel */ 111 sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 112 } 113 114 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 115 { 116 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0) 117 { 118 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0)); 119 } 120 else 121 { 122 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1)); 123 } 124 DEC_OR_INC(sx, bLeftToRight, 1); 125 } 126 DEC_OR_INC(sy, bTopToBottom, 1); 127 } 128 break; 129 130 case BMF_4BPP: 131 DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n", 132 BltInfo->DestRect.right - BltInfo->DestRect.left); 133 134 /* This sets SourceBits_4BPP to the top line */ 135 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1); 136 137 if (bTopToBottom) 138 { 139 /* This sets SourceBits_4BPP to the bottom line */ 140 SourceBits_4BPP += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta; 141 } 142 143 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 144 { 145 SourceLine_4BPP = SourceBits_4BPP; 146 sx = BltInfo->SourcePoint.x; 147 148 if (bLeftToRight) 149 { 150 /* This sets sx to the rightmost pixel */ 151 sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 152 } 153 154 f1 = sx & 1; 155 156 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 157 { 158 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 159 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1))); 160 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, xColor); 161 if(f1 == 1) 162 { 163 DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1); 164 f1 = 0; 165 } 166 else 167 { 168 f1 = 1; 169 } 170 171 DEC_OR_INC(sx, bLeftToRight, 1); 172 } 173 DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta); 174 } 175 break; 176 177 case BMF_8BPP: 178 DPRINT("8BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n", 179 BltInfo->DestRect.left, BltInfo->DestRect.top, 180 BltInfo->DestRect.right, BltInfo->DestRect.bottom, 181 BltInfo->DestRect.right - BltInfo->DestRect.left); 182 183 if ((BltInfo->XlateSourceToDest == NULL || 184 (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) && 185 (!bTopToBottom && !bLeftToRight)) 186 { 187 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) 188 { 189 DPRINT("BltInfo->DestRect.top < BltInfo->SourcePoint.y.\n"); 190 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x; 191 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 192 { 193 RtlMoveMemory(DestBits, SourceBits, BltInfo->DestRect.right - BltInfo->DestRect.left); 194 SourceBits += BltInfo->SourceSurface->lDelta; 195 DestBits += BltInfo->DestSurface->lDelta; 196 } 197 } 198 else 199 { 200 DPRINT("BltInfo->DestRect.top >= BltInfo->SourcePoint.y.\n"); 201 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x; 202 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left; 203 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--) 204 { 205 RtlMoveMemory(DestBits, SourceBits, BltInfo->DestRect.right - BltInfo->DestRect.left); 206 SourceBits -= BltInfo->SourceSurface->lDelta; 207 DestBits -= BltInfo->DestSurface->lDelta; 208 } 209 } 210 } 211 else 212 { 213 DPRINT("XO_TRIVIAL is NOT TRUE or we have flips.\n"); 214 215 if (!bTopToBottom && !bLeftToRight) 216 /* **Note: Indent is purposefully less than desired to keep reviewable differences to a minimum for PR** */ 217 { 218 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) 219 { 220 DPRINT("Dest.top < SourcePoint.y.\n"); 221 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x; 222 DestLine = DestBits; 223 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 224 { 225 SourceBits = SourceLine; 226 DestBits = DestLine; 227 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 228 { 229 *DestBits++ = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits++); 230 } 231 SourceLine += BltInfo->SourceSurface->lDelta; 232 DestLine += BltInfo->DestSurface->lDelta; 233 } 234 } 235 else 236 { 237 DPRINT("Dest.top >= SourcePoint.y.\n"); 238 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x; 239 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left; 240 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--) 241 { 242 SourceBits = SourceLine; 243 DestBits = DestLine; 244 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 245 { 246 *DestBits++ = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits++); 247 } 248 SourceLine -= BltInfo->SourceSurface->lDelta; 249 DestLine -= BltInfo->DestSurface->lDelta; 250 } 251 } 252 } 253 else 254 { 255 /* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */ 256 BOOL OneDone = FALSE; 257 258 if (bLeftToRight) 259 { 260 DPRINT("Flip is bLeftToRight.\n"); 261 262 /* Allocate enough pixels for a row in BYTE's */ 263 BYTE *store = ExAllocatePoolWithTag(NonPagedPool, 264 BltInfo->DestRect.right - BltInfo->DestRect.left + 1, TAG_DIB); 265 if (store == NULL) 266 { 267 DPRINT1("Storage Allocation Failed.\n"); 268 return FALSE; 269 } 270 WORD Index; 271 272 /* This sets SourceLine to the top line */ 273 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 274 (BltInfo->SourcePoint.y * 275 BltInfo->SourceSurface->lDelta) + 276 BltInfo->SourcePoint.x; 277 278 /* This set the DestLine to the top line */ 279 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + 280 (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 281 BltInfo->DestRect.left; 282 283 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 284 { 285 SourceBits = SourceLine; 286 DestBits = DestLine; 287 288 /* This sets SourceBits to the rightmost pixel */ 289 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 290 291 Index = 0; 292 293 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 294 { 295 store[Index] = (BYTE)XLATEOBJ_iXlate( 296 BltInfo->XlateSourceToDest, 297 *SourceBits); 298 SourceBits--; 299 Index++; 300 } 301 302 Index = 0; 303 304 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 305 { 306 *DestBits = store[Index]; 307 DestBits++; 308 Index++; 309 } 310 311 SourceLine += BltInfo->SourceSurface->lDelta; 312 DestLine += BltInfo->DestSurface->lDelta; 313 } 314 ExFreePoolWithTag(store, TAG_DIB); 315 OneDone = TRUE; 316 } 317 318 if (bTopToBottom) 319 { 320 DPRINT("Flip is bTopToBottom.\n"); 321 322 DWORD Index; 323 324 /* Allocate enough pixels for a column in BYTE's */ 325 BYTE *store = ExAllocatePoolWithTag(NonPagedPool, 326 BltInfo->DestRect.bottom - BltInfo->DestRect.top + 1, TAG_DIB); 327 if (store == NULL) 328 { 329 DPRINT1("Storage Allocation Failed.\n"); 330 return FALSE; 331 } 332 333 /* The OneDone flag indicates that we are flipping for bTopToBottom and bLeftToRight 334 * and have already completed the bLeftToRight. So we will lose our first flip output 335 * unless we work with its output which is at the destination site. So in this case 336 * our new Source becomes the previous outputs Destination. */ 337 338 if (OneDone) 339 { 340 /* This sets SourceLine to the bottom line of our previous destination */ 341 SourceLine = (PBYTE)BltInfo->DestSurface->pvScan0 + 342 (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left + 343 (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->DestSurface->lDelta; 344 } 345 else 346 { 347 /* This sets SourceLine to the bottom line */ 348 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 349 ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) 350 * BltInfo->SourceSurface->lDelta) + 351 BltInfo->SourcePoint.x; 352 } 353 354 /* This set the DestLine to the top line */ 355 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + 356 (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 357 BltInfo->DestRect.left; 358 359 /* Read columns */ 360 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 361 { 362 363 DestBits = DestLine; 364 SourceBits = SourceLine; 365 366 Index = 0; 367 368 /* Read up the column and store the pixels */ 369 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 370 { 371 store[Index] = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits); 372 /* Go up a line */ 373 SourceBits -= BltInfo->SourceSurface->lDelta; 374 Index++; 375 } 376 377 Index = 0; 378 379 /* Get the stored pixel and copy then down the column */ 380 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 381 { 382 *DestBits = store[Index]; 383 /* Go down a line */ 384 DestBits += BltInfo->SourceSurface->lDelta; 385 Index++; 386 } 387 /* Index to next column */ 388 SourceLine += 1; 389 DestLine += 1; 390 } 391 ExFreePoolWithTag(store, TAG_DIB); 392 } 393 394 } 395 } 396 break; 397 398 case BMF_16BPP: 399 DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n", 400 BltInfo->DestRect.right - BltInfo->DestRect.left); 401 402 DPRINT("BMF_16BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n", 403 BltInfo->DestRect.left, BltInfo->DestRect.top, 404 BltInfo->DestRect.right, BltInfo->DestRect.bottom, 405 BltInfo->DestRect.right - BltInfo->DestRect.left); 406 407 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x; 408 409 if (bTopToBottom) 410 { 411 /* This sets SourceLine to the bottom line */ 412 SourceLine += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;; 413 } 414 DestLine = DestBits; 415 416 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 417 { 418 SourceBits = SourceLine; 419 420 if (bLeftToRight) 421 { 422 /* This sets SourceBits to the rightmost pixel */ 423 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 2; 424 } 425 DestBits = DestLine; 426 427 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 428 { 429 xColor = *((PWORD) SourceBits); 430 *DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor); 431 432 DEC_OR_INC(SourceBits, bLeftToRight, 2); 433 DestBits += 1; 434 } 435 DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta); 436 DestLine += BltInfo->DestSurface->lDelta; 437 } 438 break; 439 440 case BMF_24BPP: 441 DPRINT("24BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n", 442 BltInfo->DestRect.left, BltInfo->DestRect.top, 443 BltInfo->DestRect.right, BltInfo->DestRect.bottom, 444 BltInfo->DestRect.right - BltInfo->DestRect.left); 445 446 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x; 447 DestLine = DestBits; 448 449 if (bTopToBottom) 450 { 451 /* This sets SourceLine to the bottom line */ 452 SourceLine += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1); 453 } 454 455 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 456 { 457 SourceBits = SourceLine; 458 DestBits = DestLine; 459 460 if (bLeftToRight) 461 { 462 /* This sets the SourceBits to the rightmost pixel */ 463 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 3; 464 } 465 466 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 467 { 468 xColor = (*(SourceBits + 2) << 0x10) + 469 (*(SourceBits + 1) << 0x08) + 470 (*(SourceBits)); 471 *DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor); 472 DEC_OR_INC(SourceBits, bLeftToRight, 3); 473 DestBits += 1; 474 } 475 DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta); 476 DestLine += BltInfo->DestSurface->lDelta; 477 } 478 break; 479 480 case BMF_32BPP: 481 DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n", 482 BltInfo->DestRect.right - BltInfo->DestRect.left); 483 484 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x; 485 486 if (bTopToBottom) 487 { 488 /* This sets SourceLine to the bottom line */ 489 SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1; 490 } 491 DestLine = DestBits; 492 493 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 494 { 495 SourceBits = SourceLine; 496 DestBits = DestLine; 497 498 if (bLeftToRight) 499 { 500 /* This sets SourceBits to the rightmost pixel */ 501 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4; 502 } 503 504 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 505 { 506 xColor = *((PDWORD) SourceBits); 507 *DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor); 508 509 DEC_OR_INC(SourceBits, bLeftToRight, 4); 510 DestBits += 1; 511 } 512 DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta); 513 DestLine += BltInfo->DestSurface->lDelta; 514 } 515 break; 516 517 default: 518 DPRINT1("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat)); 519 return FALSE; 520 } 521 522 return TRUE; 523 } 524 525 /* BitBlt Optimize */ 526 BOOLEAN 527 DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color) 528 { 529 LONG DestY; 530 531 /* Make WellOrdered by making top < bottom and left < right */ 532 RECTL_vMakeWellOrdered(DestRect); 533 534 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++) 535 { 536 DIB_8BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color); 537 } 538 return TRUE; 539 } 540 541 542 BOOLEAN 543 DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 544 RECTL* DestRect, RECTL *SourceRect, 545 XLATEOBJ *ColorTranslation, ULONG iTransColor) 546 { 547 LONG RoundedRight, X, Y, SourceX = 0, SourceY = 0; 548 ULONG *DestBits, Source, Dest; 549 550 LONG DstHeight; 551 LONG DstWidth; 552 LONG SrcHeight; 553 LONG SrcWidth; 554 555 DstHeight = DestRect->bottom - DestRect->top; 556 DstWidth = DestRect->right - DestRect->left; 557 SrcHeight = SourceRect->bottom - SourceRect->top; 558 SrcWidth = SourceRect->right - SourceRect->left; 559 560 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3); 561 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left + 562 (DestRect->top * DestSurf->lDelta)); 563 564 for(Y = DestRect->top; Y < DestRect->bottom; Y++) 565 { 566 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left + 567 (Y * DestSurf->lDelta)); 568 SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight; 569 for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++) 570 { 571 Dest = *DestBits; 572 573 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth; 574 if (SourceX >= 0 && SourceY >= 0 && 575 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 576 { 577 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 578 if(Source != iTransColor) 579 { 580 Dest &= 0xFFFFFF00; 581 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF); 582 } 583 } 584 585 SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth; 586 if (SourceX >= 0 && SourceY >= 0 && 587 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 588 { 589 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 590 if(Source != iTransColor) 591 { 592 Dest &= 0xFFFF00FF; 593 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00); 594 } 595 } 596 597 SourceX = SourceRect->left+(X+2 - DestRect->left) * SrcWidth / DstWidth; 598 if (SourceX >= 0 && SourceY >= 0 && 599 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 600 { 601 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 602 if(Source != iTransColor) 603 { 604 Dest &= 0xFF00FFFF; 605 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000); 606 } 607 } 608 609 SourceX = SourceRect->left+(X+3 - DestRect->left) * SrcWidth / DstWidth; 610 if (SourceX >= 0 && SourceY >= 0 && 611 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 612 { 613 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 614 if(Source != iTransColor) 615 { 616 Dest &= 0x00FFFFFF; 617 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000); 618 } 619 } 620 621 *DestBits = Dest; 622 } 623 624 if(X < DestRect->right) 625 { 626 for (; X < DestRect->right; X++) 627 { 628 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth; 629 if (SourceX >= 0 && SourceY >= 0 && 630 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 631 { 632 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 633 if(Source != iTransColor) 634 { 635 *((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF); 636 } 637 } 638 DestBits = (PULONG)((ULONG_PTR)DestBits + 1); 639 } 640 } 641 } 642 643 return TRUE; 644 } 645 646 /* EOF */ 647