mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 11:33:31 +08:00
[WIN32K] Add StretchBlt function ability to flip images (#3458)
Modify dib\dibxxbpp.c programs to understand flipped images. See Videos at CORE-16642 1. Mirroring Horizontally works. 2. Mirroring Vertically works. 3. Rotation 180° works. CORE-16642, CORE-14408, CORE-16634
This commit is contained in:
parent
89843bec56
commit
ce7836c6d3
@ -6,6 +6,7 @@
|
||||
* PROGRAMMERS: Jason Filby
|
||||
* Thomas Bluemel
|
||||
* Gregor Anich
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -13,6 +14,9 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define DEC_OR_INC(var, decTrue, amount) \
|
||||
((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
|
||||
|
||||
VOID
|
||||
DIB_16BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
|
||||
{
|
||||
@ -142,17 +146,66 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
LONG i, j, sx, sy, xColor, f1;
|
||||
PBYTE SourceBits, DestBits, SourceLine, DestLine;
|
||||
PBYTE SourceBits_4BPP, SourceLine_4BPP;
|
||||
PWORD Source32, Dest32;
|
||||
DWORD Index, StartLeft, EndRight;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
DPRINT("DIB_16BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
|
||||
BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
/* Get back left to right flip here */
|
||||
bLeftToRight = BltInfo->DestRect.left > BltInfo->DestRect.right;
|
||||
|
||||
/* Check for top to bottom flip needed. */
|
||||
bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
|
||||
|
||||
DPRINT("BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
/* Make WellOrdered with top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(&BltInfo->DestRect);
|
||||
|
||||
DPRINT("BPP is '%d/%d' & BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourceSurface->iBitmapFormat, BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 2 * BltInfo->DestRect.left;
|
||||
|
||||
switch(BltInfo->SourceSurface->iBitmapFormat)
|
||||
{
|
||||
case BMF_1BPP:
|
||||
DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets sy to the bottom line */
|
||||
sy += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
StartLeft = BltInfo->DestRect.left + 1;
|
||||
EndRight = BltInfo->DestRect.right + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
StartLeft = BltInfo->DestRect.left;
|
||||
EndRight = BltInfo->DestRect.right;
|
||||
}
|
||||
|
||||
for (i = StartLeft; i < EndRight; i++)
|
||||
{
|
||||
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
|
||||
{
|
||||
@ -164,21 +217,37 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
DIB_16BPP_PutPixel(BltInfo->DestSurface, i, j,
|
||||
XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_4BPP:
|
||||
DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceBits_4BPP to the top line */
|
||||
SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
(BltInfo->SourcePoint.x >> 1);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceBits_4BPP to the bottom line */
|
||||
SourceBits_4BPP += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceLine_4BPP = SourceBits_4BPP;
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
f1 = sx & 1;
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
@ -188,49 +257,76 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
DIB_16BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
|
||||
if(f1 == 1)
|
||||
{
|
||||
SourceLine_4BPP++;
|
||||
DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1);
|
||||
f1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f1 = 1;
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_8BPP:
|
||||
DPRINT("8BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
BltInfo->SourcePoint.x;
|
||||
DestLine = DestBits;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta
|
||||
* (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(
|
||||
BltInfo->XlateSourceToDest, *SourceBits);
|
||||
SourceBits += 1;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 1);
|
||||
DestBits += 2;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_16BPP:
|
||||
if (NULL == BltInfo->XlateSourceToDest || 0 !=
|
||||
(BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
|
||||
DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
DPRINT("BMF_16BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if ((BltInfo->XlateSourceToDest == NULL ||
|
||||
(BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) &&
|
||||
(!bTopToBottom && !bLeftToRight))
|
||||
{
|
||||
DPRINT("XO_TRIVIAL is TRUE.\n");
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
/* This sets SourceBits to the top line */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y *
|
||||
BltInfo->SourceSurface->lDelta) + 2 *
|
||||
@ -248,6 +344,7 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This sets SourceBits to the bottom line */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom -
|
||||
BltInfo->DestRect.top - 1) *
|
||||
@ -273,6 +370,11 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("XO_TRIVIAL is NOT TRUE.\n");
|
||||
if (!bTopToBottom && !bLeftToRight)
|
||||
/* **Note: Indent is purposefully less than desired to keep reviewable differences to a minimum for PR** */
|
||||
{
|
||||
DPRINT("Flip is None.\n");
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
@ -330,14 +432,165 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
DestLine -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */
|
||||
BOOL TopToBottomDone = FALSE;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
DPRINT("Flip is bLeftToRight.\n");
|
||||
|
||||
/* Allocate enough pixels for a row in WORD's */
|
||||
WORD *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
(BltInfo->DestRect.right - BltInfo->DestRect.left + 1) * 2, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
WORD Index;
|
||||
|
||||
/* This sets SourceBits to the bottom line */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1)
|
||||
* BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
|
||||
|
||||
/* Sets DestBits to the bottom line */
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ (BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta
|
||||
+ 2 * BltInfo->DestRect.left + 2;
|
||||
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
{
|
||||
/* Set Dest32 to right pixel */
|
||||
Dest32 = (WORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
Source32 = (WORD *) SourceBits;
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Store pixels from left to right */
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
store[Index] = (WORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *(WORD *)Source32++);
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Copy stored data to pixels from right to left */
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
*(WORD *)Dest32-- = store[Index];
|
||||
Index++;
|
||||
}
|
||||
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
TopToBottomDone = TRUE;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
DPRINT("Flip is bTopToBottom.\n");
|
||||
|
||||
/* Allocate enough pixels for a column in WORD's */
|
||||
WORD *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
(BltInfo->DestRect.bottom - BltInfo->DestRect.top + 1) * 2, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This set SourceBits to the top line */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 2 * BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets DestBits to the top line */
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ ((BltInfo->DestRect.top) * BltInfo->DestSurface->lDelta)
|
||||
+ 2 * BltInfo->DestRect.left;
|
||||
|
||||
if ((BltInfo->SourceSurface->fjBitmap & BMF_TOPDOWN) == 0)
|
||||
{
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
DPRINT("Adjusting DestBits for bLeftToRight.\n");
|
||||
DestBits += 2;
|
||||
}
|
||||
|
||||
/* The TopToBottomDone flag indicates that we are flipping for bTopToBottom and bLeftToRight
|
||||
* and have already completed the bLeftToRight. So we will lose our first flip output
|
||||
* unless we work with its output which is at the destination site. So in this case
|
||||
* our new Source becomes the previous outputs Destination. */
|
||||
|
||||
if (TopToBottomDone)
|
||||
{
|
||||
/* This sets SourceBits to the top line */
|
||||
SourceBits = DestBits;
|
||||
}
|
||||
|
||||
for (j = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= j ; j--)
|
||||
{
|
||||
/* Set Dest32 to bottom pixel */
|
||||
Dest32 = (WORD *) DestBits + (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1)
|
||||
* BltInfo->DestSurface->lDelta / 2;
|
||||
Source32 = (WORD *) SourceBits;
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Store pixels from top to bottom */
|
||||
for (i = BltInfo->DestRect.top; i <= BltInfo->DestRect.bottom - 1; i++)
|
||||
{
|
||||
store[Index] = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32);
|
||||
Source32 += BltInfo->SourceSurface->lDelta / 2;
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Copy stored data to pixels from bottom to top */
|
||||
for (i = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= i; i--)
|
||||
{
|
||||
*Dest32 = store[Index];
|
||||
Dest32 -= BltInfo->DestSurface->lDelta / 2;
|
||||
Index++;
|
||||
}
|
||||
SourceBits += 2;
|
||||
DestBits += 2;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_24BPP:
|
||||
|
||||
DPRINT("BMF_24BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
3 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -345,6 +598,11 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 3;
|
||||
}
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = (*(SourceBits + 2) << 0x10) +
|
||||
@ -353,19 +611,27 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
*((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(
|
||||
BltInfo->XlateSourceToDest, xColor);
|
||||
|
||||
SourceBits += 3;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 3);
|
||||
DestBits += 2;
|
||||
}
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_32BPP:
|
||||
DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
4 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
|
||||
}
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -373,23 +639,29 @@ DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4;
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(
|
||||
BltInfo->XlateSourceToDest,
|
||||
*((PDWORD) SourceBits));
|
||||
SourceBits += 4;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 4);
|
||||
DestBits += 2;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n",
|
||||
BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
|
||||
DPRINT1("DIB_16BPP_BitBltSrcCopy: Unhandled Source BPP: %u\n",
|
||||
BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -402,6 +674,9 @@ DIB_16BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
|
||||
{
|
||||
LONG DestY;
|
||||
|
||||
/* Make WellOrdered with top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
#if defined(_M_IX86) && !defined(_MSC_VER)
|
||||
/* This is about 10% faster than the generic C code below */
|
||||
ULONG delta = DestSurface->lDelta;
|
||||
|
@ -4,6 +4,7 @@
|
||||
* FILE: win32ss/gdi/dib/dib1bpp.c
|
||||
* PURPOSE: Device Independant Bitmap functions, 1bpp
|
||||
* PROGRAMMERS: Jason Filby
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -11,6 +12,9 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define DEC_OR_INC(var, decTrue, amount) \
|
||||
((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
|
||||
|
||||
VOID
|
||||
DIB_1BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
|
||||
{
|
||||
@ -57,13 +61,18 @@ DIB_1BPP_BitBltSrcCopy_From1BPP (
|
||||
SURFOBJ* SourceSurf,
|
||||
XLATEOBJ* pxlo,
|
||||
PRECTL DestRect,
|
||||
POINTL *SourcePoint )
|
||||
POINTL *SourcePoint,
|
||||
BOOLEAN bTopToBottom,
|
||||
BOOLEAN bLeftToRight )
|
||||
{
|
||||
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
// The 'window' in this sense is the x-position that corresponds
|
||||
// to the left-edge of the 8-pixel byte we are currently working with.
|
||||
// dwx is current x-window, dwx2 is the 'last' window we need to process.
|
||||
int dwx, dwx2; // Destination window x-position
|
||||
int swx; // Source window y-position
|
||||
int swx; // Source window x-position
|
||||
|
||||
// Left and right edges of source and dest rectangles
|
||||
int dl = DestRect->left; // dest left
|
||||
@ -96,39 +105,75 @@ DIB_1BPP_BitBltSrcCopy_From1BPP (
|
||||
|
||||
if ( DestRect->top <= SourcePoint->y )
|
||||
{
|
||||
DPRINT("Moving up (scan top -> bottom).\n");
|
||||
// Moving up (scan top -> bottom)
|
||||
dy1 = DestRect->top;
|
||||
dy2 = DestRect->bottom - 1;
|
||||
sy1 = SourcePoint->y;
|
||||
if (bTopToBottom)
|
||||
{
|
||||
sy1 = SourcePoint->y + dy2 - dy1;
|
||||
ySrcDelta = -SourceSurf->lDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
sy1 = SourcePoint->y;
|
||||
ySrcDelta = SourceSurf->lDelta;
|
||||
}
|
||||
yinc = 1;
|
||||
ySrcDelta = SourceSurf->lDelta;
|
||||
yDstDelta = DestSurf->lDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Moving down (scan bottom -> top).\n");
|
||||
// Moving down (scan bottom -> top)
|
||||
dy1 = DestRect->bottom - 1;
|
||||
dy2 = DestRect->top;
|
||||
sy1 = SourcePoint->y + dy1 - dy2;
|
||||
if (bTopToBottom)
|
||||
{
|
||||
sy1 = SourcePoint->y;
|
||||
ySrcDelta = SourceSurf->lDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
sy1 = SourcePoint->y + dy1 - dy2;
|
||||
ySrcDelta = -SourceSurf->lDelta;
|
||||
}
|
||||
yinc = -1;
|
||||
ySrcDelta = -SourceSurf->lDelta;
|
||||
yDstDelta = -DestSurf->lDelta;
|
||||
}
|
||||
if ( DestRect->left <= SourcePoint->x )
|
||||
{
|
||||
DPRINT("Moving left (scan left->right).\n");
|
||||
// Moving left (scan left->right)
|
||||
dwx = dl&~7;
|
||||
swx = (sl-(dl&7))&~7;
|
||||
dwx2 = dr&~7;
|
||||
xinc = 1;
|
||||
if (bLeftToRight)
|
||||
{
|
||||
swx = (sr - (dr & 7)) & ~7;
|
||||
xinc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
swx = (sl-(dl&7))&~7;
|
||||
xinc = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Moving right (scan right->left).\n");
|
||||
// Moving right (scan right->left)
|
||||
dwx = dr & ~7;
|
||||
swx = (sr - (dr & 7)) & ~7; // (sr - 7) & ~7; // We need the left edge of this block. Thus the -7
|
||||
dwx2 = dl & ~7;
|
||||
xinc = -1;
|
||||
if (bLeftToRight)
|
||||
{
|
||||
swx = (sl-(dl&7))&~7;
|
||||
xinc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
swx = (sr - (dr & 7)) & ~7; // (sr - 7) & ~7; // We need the left edge of this block. Thus the -7
|
||||
xinc = -1;
|
||||
}
|
||||
}
|
||||
d = &(((PBYTE)DestSurf->pvScan0)[dy1*DestSurf->lDelta + (dwx>>3)]);
|
||||
s = &(((PBYTE)SourceSurf->pvScan0)[sy1*SourceSurf->lDelta + (swx>>3)]);
|
||||
@ -227,81 +272,199 @@ BOOLEAN
|
||||
DIB_1BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
{
|
||||
ULONG Color;
|
||||
LONG i, j, sx, sy = BltInfo->SourcePoint.y;
|
||||
LONG i, j, sx, sy;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
// This sets sy to the top line
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
DPRINT("DIB_1BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
|
||||
BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
/* Get back left to right flip here */
|
||||
bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right);
|
||||
|
||||
/* Check for top to bottom flip needed. */
|
||||
bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
|
||||
|
||||
// Make WellOrdered with top < bottom and left < right
|
||||
RECTL_vMakeWellOrdered(&BltInfo->DestRect);
|
||||
|
||||
DPRINT("BPP is '%d' & BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourceSurface->iBitmapFormat, BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
switch ( BltInfo->SourceSurface->iBitmapFormat )
|
||||
{
|
||||
case BMF_1BPP:
|
||||
DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo->DestSurface, BltInfo->SourceSurface, BltInfo->XlateSourceToDest, &BltInfo->DestRect, &BltInfo->SourcePoint );
|
||||
DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
DIB_1BPP_BitBltSrcCopy_From1BPP ( BltInfo->DestSurface, BltInfo->SourceSurface,
|
||||
BltInfo->XlateSourceToDest, &BltInfo->DestRect, &BltInfo->SourcePoint,
|
||||
bTopToBottom, bLeftToRight );
|
||||
break;
|
||||
|
||||
case BMF_4BPP:
|
||||
DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
// This sets sy to the bottom line
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
// This sets the sx to the rightmost pixel
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
|
||||
sx++;
|
||||
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_8BPP:
|
||||
DPRINT("8BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
// This sets sy to the bottom line
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
// This sets sx to the rightmost pixel
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_8BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
|
||||
sx++;
|
||||
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_16BPP:
|
||||
DPRINT("16BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
// This sets sy to the bottom line
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
// This sets the sx to the rightmost pixel
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_16BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_24BPP:
|
||||
|
||||
DPRINT("24BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
// This sets sy to the bottom line
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
// This sets the sx to the rightmost pixel
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_32BPP:
|
||||
|
||||
DPRINT("32BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
// This sets sy to the bottom line
|
||||
sy += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
// This sets the sx to the rightmost pixel
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
Color = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_32BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
DIB_1BPP_PutPixel(BltInfo->DestSurface, i, j, Color);
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -460,6 +623,9 @@ DIB_1BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
|
||||
{
|
||||
LONG DestY;
|
||||
|
||||
/* Make WellOrdered with top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
|
||||
{
|
||||
DIB_1BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
|
||||
|
@ -6,6 +6,7 @@
|
||||
* PROGRAMMERS: Jason Filby
|
||||
* Thomas Bluemel
|
||||
* Gregor Anich
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -13,6 +14,9 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define DEC_OR_INC(var, decTrue, amount) \
|
||||
((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
|
||||
|
||||
VOID
|
||||
DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
|
||||
{
|
||||
@ -53,6 +57,24 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
PBYTE SourceBits, DestBits, SourceLine, DestLine;
|
||||
PBYTE SourceBits_4BPP, SourceLine_4BPP;
|
||||
PWORD SourceBits_16BPP, SourceLine_16BPP;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
DPRINT("DIB_24BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
|
||||
BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
/* Get back left to right flip here */
|
||||
bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right);
|
||||
|
||||
/* Check for top to bottom flip needed. */
|
||||
bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
|
||||
|
||||
DPRINT("BltInfo->SourcePoint.x is '%d' and BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
/* Make WellOrdered by making top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(&BltInfo->DestRect);
|
||||
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
|
||||
|
||||
@ -60,11 +82,26 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
{
|
||||
case BMF_1BPP:
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets sy to the bottom line */
|
||||
sy += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
|
||||
@ -73,20 +110,37 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
} else {
|
||||
DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_4BPP:
|
||||
DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceBits_4BPP to the top line */
|
||||
SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceBits_4BPP to the bottom line */
|
||||
SourceBits_4BPP += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceLine_4BPP = SourceBits_4BPP;
|
||||
DestLine = DestBits;
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
f1 = sx & 1;
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
@ -96,17 +150,33 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
*DestLine++ = xColor & 0xff;
|
||||
*(PWORD)DestLine = (WORD)(xColor >> 8);
|
||||
DestLine += 2;
|
||||
if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
|
||||
sx++;
|
||||
if(f1 == 1) {
|
||||
DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1);
|
||||
f1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f1 = 1;
|
||||
}
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
|
||||
SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_8BPP:
|
||||
DPRINT("8BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -114,47 +184,83 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
|
||||
*DestBits = xColor & 0xff;
|
||||
*(PWORD)(DestBits + 1) = (WORD)(xColor >> 8);
|
||||
SourceBits += 1;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 1);
|
||||
DestBits += 3;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_16BPP:
|
||||
DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceBits_16BPP to the top line */
|
||||
SourceBits_16BPP = (PWORD)((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceBits_16BPP to the bottom line */
|
||||
SourceBits_16BPP += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceLine_16BPP = SourceBits_16BPP;
|
||||
DestLine = DestBits;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceLine_16BPP to the rightmost pixel */
|
||||
SourceLine_16BPP += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_16BPP);
|
||||
*DestLine++ = xColor & 0xff;
|
||||
*(PWORD)DestLine = (WORD)(xColor >> 8);
|
||||
DestLine += 2;
|
||||
SourceLine_16BPP++;
|
||||
DEC_OR_INC(SourceLine_16BPP, bLeftToRight, 1);
|
||||
}
|
||||
if (bTopToBottom)
|
||||
{
|
||||
SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP - BltInfo->SourceSurface->lDelta);
|
||||
}
|
||||
else
|
||||
{
|
||||
SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
|
||||
}
|
||||
|
||||
SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_24BPP:
|
||||
if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
|
||||
DPRINT("24BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* Check for no flips here because we are about to use RtlMoveMemory and it can only do increasing src & dst */
|
||||
if ((BltInfo->XlateSourceToDest == NULL ||
|
||||
(BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) &&
|
||||
(!bTopToBottom && !bLeftToRight))
|
||||
{
|
||||
DPRINT("XO_TRIVIAL is TRUE.\n");
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
/* This sets SourceBits to the top line */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
@ -176,6 +282,11 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("XO_TRIVIAL is NOT TRUE.\n");
|
||||
|
||||
if (!bTopToBottom && !bLeftToRight)
|
||||
/* **Note: Indent is purposefully less than desired to keep reviewable differences to a minimum for PR** */
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
@ -191,11 +302,151 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
sy++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */
|
||||
BOOL TopToBottomDone = FALSE;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
DPRINT("Flip is bLeftToRight.\n");
|
||||
DWORD Index;
|
||||
|
||||
/* Allocate enough pixels for a row in DWORD's */
|
||||
DWORD *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
(BltInfo->DestRect.right - BltInfo->DestRect.left + 1) * 4, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx = BltInfo->SourcePoint.x + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx = BltInfo->SourcePoint.x + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
|
||||
Index = 0;
|
||||
|
||||
// Read right to left and store
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
store[Index] = DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy);
|
||||
Index++;
|
||||
sx--;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
// Write left to right to pixel
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, store[Index]));
|
||||
Index++;
|
||||
}
|
||||
sy++;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
TopToBottomDone = TRUE;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
DPRINT("Flip is bTopToBottom.\n");
|
||||
DWORD Index;
|
||||
|
||||
/* Allocate enough pixels for a column in DWORD's */
|
||||
DWORD *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
(BltInfo->DestRect.bottom - BltInfo->DestRect.top + 1) * 4, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The TopToBottomDone flag indicates that we are flipping for bTopToBottom and bLeftToRight
|
||||
* and have already completed the bLeftToRight. So we will lose our first flip output
|
||||
* unless we work with its output which is at the destination site. So in this case
|
||||
* our new Source becomes the previous outputs Destination.
|
||||
*/
|
||||
|
||||
if (TopToBottomDone)
|
||||
{
|
||||
sx = BltInfo->DestRect.left;
|
||||
sy = BltInfo->DestRect.top;
|
||||
|
||||
/* This sets sy to the bottom line */
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
/* This sets sy to the bottom line */
|
||||
sy = BltInfo->SourcePoint.y + (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
|
||||
/* This sets sy to the bottom line */
|
||||
sy = BltInfo->SourcePoint.y + (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
Index = 0;
|
||||
|
||||
/* Read bottom to top and store */
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
if (TopToBottomDone)
|
||||
{
|
||||
store[Index] = DIB_24BPP_GetPixel(BltInfo->DestSurface, sx, sy);
|
||||
}
|
||||
else
|
||||
{
|
||||
store[Index] = DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy);
|
||||
}
|
||||
Index++;
|
||||
sy--;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, store[Index]));
|
||||
Index++;
|
||||
}
|
||||
sx++;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_32BPP:
|
||||
DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
|
||||
}
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -203,16 +454,21 @@ DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4;
|
||||
}
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
|
||||
*DestBits = xColor & 0xff;
|
||||
*(PWORD)(DestBits + 1) = (WORD)(xColor >> 8);
|
||||
SourceBits += 4;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 4);
|
||||
DestBits += 3;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
@ -255,7 +511,9 @@ DIB_24BPP_BitBlt(PBLTINFO BltInfo)
|
||||
else
|
||||
{
|
||||
if (BltInfo->Brush)
|
||||
{
|
||||
Pattern = BltInfo->Brush->iSolidColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,6 +559,9 @@ DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
|
||||
{
|
||||
LONG DestY;
|
||||
|
||||
/* Make WellOrdered by making top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
#if defined(_M_IX86) && !defined(_MSC_VER)
|
||||
PBYTE xaddr = (PBYTE)DestSurface->pvScan0 + DestRect->top * DestSurface->lDelta + (DestRect->left << 1) + DestRect->left;
|
||||
PBYTE addr;
|
||||
|
@ -6,6 +6,7 @@
|
||||
* PROGRAMMERS: Jason Filby
|
||||
* Thomas Bluemel
|
||||
* Gregor Anich
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -13,6 +14,9 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define DEC_OR_INC(var, decTrue, amount) \
|
||||
((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
|
||||
|
||||
VOID
|
||||
DIB_32BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
|
||||
{
|
||||
@ -51,46 +55,137 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
{
|
||||
LONG i, j, sx, sy, xColor, f1;
|
||||
PBYTE SourceBits, DestBits, SourceLine, DestLine;
|
||||
PBYTE SourceBitsT, SourceBitsB, DestBitsT, DestBitsB;
|
||||
PBYTE SourceBits_4BPP, SourceLine_4BPP;
|
||||
PDWORD Source32, Dest32;
|
||||
DWORD Index, DestWidth, DestHeight;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
BOOLEAN blDeltaSrcNeg, blDeltaDestNeg;
|
||||
BOOLEAN blDeltaAdjustDone = FALSE;
|
||||
|
||||
DPRINT("DIB_32BPP_BitBltSrcCopy: SourcePoint (%d, %d), SourceSurface cx/cy (%d/%d), "
|
||||
"DestSurface cx/cy (%d/%d) DestRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo->SourcePoint.x, BltInfo->SourcePoint.y,
|
||||
BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
|
||||
BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
DPRINT("BltInfo->DestSurface->lDelta is '%d' and BltInfo->SourceSurface->lDelta is '%d'.\n",
|
||||
BltInfo->DestSurface->lDelta, BltInfo->SourceSurface->lDelta);
|
||||
|
||||
DPRINT("iBitmapFormat is %d and width,height is (%d,%d).\n", BltInfo->SourceSurface->iBitmapFormat,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left, BltInfo->DestRect.bottom - BltInfo->DestRect.top);
|
||||
|
||||
DPRINT("BltInfo->SourcePoint.x is '%d' and BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
/* Do not deal with negative numbers for these values */
|
||||
if ((BltInfo->DestRect.left < 0) || (BltInfo->DestRect.top < 0) ||
|
||||
(BltInfo->DestRect.right < 0) || (BltInfo->DestRect.bottom < 0))
|
||||
return FALSE;
|
||||
|
||||
/* Detect negative lDelta's meaning Bottom-Up bitmaps */
|
||||
blDeltaSrcNeg = BltInfo->SourceSurface->lDelta < 0;
|
||||
blDeltaDestNeg = BltInfo->DestSurface->lDelta < 0;
|
||||
|
||||
/* Get back left to right flip here */
|
||||
bLeftToRight = BltInfo->DestRect.left > BltInfo->DestRect.right;
|
||||
|
||||
/* Check for top to bottom flip needed. */
|
||||
bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
|
||||
|
||||
DPRINT("bTopToBottom is '%d' and DestSurface->lDelta < 0 is '%d' and SourceSurface->lDelta < 0 is '%d'.\n",
|
||||
bTopToBottom, BltInfo->DestSurface->lDelta < 0 ? 1 : 0, BltInfo->SourceSurface->lDelta < 0 ? 1 : 0);
|
||||
|
||||
/* Make WellOrdered with top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(&BltInfo->DestRect);
|
||||
|
||||
DestWidth = BltInfo->DestRect.right - BltInfo->DestRect.left;
|
||||
DestHeight = BltInfo->DestRect.bottom - BltInfo->DestRect.top;
|
||||
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta)
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
|
||||
DPRINT("iBitmapFormat is %d and width,height is (%d,%d).\n", BltInfo->SourceSurface->iBitmapFormat,
|
||||
DestWidth, DestHeight);
|
||||
|
||||
switch (BltInfo->SourceSurface->iBitmapFormat)
|
||||
{
|
||||
case BMF_1BPP:
|
||||
DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
DestWidth);
|
||||
|
||||
if (bLeftToRight || bTopToBottom)
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets sy to the bottom line */
|
||||
sy += BltInfo->SourceSurface->lDelta * (DestHeight - 1);
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the sx to the rightmost pixel */
|
||||
sx += (DestWidth - 1);
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
if (DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
|
||||
{
|
||||
DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
|
||||
}
|
||||
sx++;
|
||||
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_4BPP:
|
||||
DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
DestWidth);
|
||||
|
||||
if (bLeftToRight || bTopToBottom)
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
/* This sets SourceBits_4BPP to the top line */
|
||||
SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ (BltInfo->SourcePoint.x >> 1);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceBits_4BPP to the bottom line */
|
||||
SourceBits_4BPP += BltInfo->SourceSurface->lDelta * (DestHeight - 1);
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceLine_4BPP = SourceBits_4BPP;
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx += (DestWidth - 1);
|
||||
}
|
||||
|
||||
f1 = sx & 1;
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
@ -99,66 +194,120 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
(*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
|
||||
DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
|
||||
if (f1 == 1) {
|
||||
SourceLine_4BPP++;
|
||||
DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1);
|
||||
f1 = 0;
|
||||
} else {
|
||||
f1 = 1;
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
|
||||
SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_8BPP:
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
DPRINT("8BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
DestWidth);
|
||||
|
||||
if (bLeftToRight || bTopToBottom)
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ BltInfo->SourcePoint.x;
|
||||
DestLine = DestBits;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta * (DestHeight - 1);
|
||||
}
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits to the rightmost pixel */
|
||||
SourceBits += (DestWidth - 1);
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = *SourceBits;
|
||||
*((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
|
||||
SourceBits += 1;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 1);
|
||||
DestBits += 4;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_16BPP:
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
|
||||
DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
DestWidth);
|
||||
|
||||
if (bLeftToRight || bTopToBottom)
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 2 * BltInfo->SourcePoint.x;
|
||||
DestLine = DestBits;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta * (DestHeight - 1);
|
||||
}
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits to the rightmost pixel */
|
||||
SourceBits += (DestWidth - 1) * 2;
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = *((PWORD) SourceBits);
|
||||
*((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
|
||||
SourceBits += 2;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 2);
|
||||
DestBits += 4;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_24BPP:
|
||||
DPRINT("24BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
DestWidth);
|
||||
|
||||
if (bLeftToRight || bTopToBottom)
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 3 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta * (DestHeight - 1);
|
||||
}
|
||||
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -166,46 +315,109 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits to the rightmost pixel */
|
||||
SourceBits += (DestWidth - 1) * 3;
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = (*(SourceBits + 2) << 0x10) +
|
||||
(*(SourceBits + 1) << 0x08) +
|
||||
(*(SourceBits));
|
||||
*((PDWORD)DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
|
||||
SourceBits += 3;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 3);
|
||||
DestBits += 4;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_32BPP:
|
||||
if (NULL == BltInfo->XlateSourceToDest ||
|
||||
0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
|
||||
DPRINT("32BPP Case Selected with SourcePoint (%d,%d) and DestRect Width/height of '%d/%d' DestRect: (%d,%d)-(%d,%d).\n",
|
||||
BltInfo->SourcePoint.x, BltInfo->SourcePoint.y, DestWidth, DestHeight,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
if (bLeftToRight || bTopToBottom)
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
/* This handles the negative lDelta's which represent Top-to-Bottom bitmaps */
|
||||
if (((blDeltaSrcNeg || blDeltaDestNeg) && !(blDeltaSrcNeg && blDeltaDestNeg)) && bTopToBottom)
|
||||
{
|
||||
DPRINT("Adjusting for lDelta's here.\n");
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
/* SourceBits points to top-left pixel for lDelta < 0 and bottom-left for lDelta > 0 */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * DestWidth);
|
||||
SourceBits += BltInfo->SourceSurface->lDelta;
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SourceBits points to bottom-left pixel for lDelta < 0 and top-left for lDelta > 0 */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y
|
||||
+ BltInfo->DestRect.bottom
|
||||
- BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta)
|
||||
+ DestHeight - 1) * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
|
||||
/* SourceBits points to bottom-left pixel for lDelta < 0 and top-left for lDelta > 0 */
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta)
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
{
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * DestWidth);
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
blDeltaAdjustDone = TRUE;
|
||||
}
|
||||
|
||||
/* This tests for whether we can use simplified/quicker code below.
|
||||
* It works for increasing source and destination areas only and there is no overlap and no flip.
|
||||
*/
|
||||
if ((BltInfo->XlateSourceToDest == NULL ||
|
||||
(BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) &&
|
||||
(!bTopToBottom && !bLeftToRight))
|
||||
{
|
||||
DPRINT("XO_TRIVIAL is TRUE.\n");
|
||||
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
/* SourceBits points to top-left pixel for lDelta < 0 and bottom-left for lDelta > 0 */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * DestWidth);
|
||||
SourceBits += BltInfo->SourceSurface->lDelta;
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SourceBits points to bottom-left pixel for lDelta < 0 and top-left for lDelta > 0 */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y
|
||||
+ DestHeight - 1) * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
/* SourceBits points to bottom-left pixel for lDelta < 0 and top-left for lDelta > 0 */
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta)
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
{
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * DestWidth);
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
@ -213,66 +425,272 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
DPRINT("XO_TRIVIAL is NOT TRUE.\n");
|
||||
|
||||
if (!bTopToBottom && !bLeftToRight)
|
||||
{
|
||||
SourceBits = ((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x);
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
|
||||
SourceBits = ((PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x);
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
Dest32 = (DWORD *) DestBits;
|
||||
Source32 = (DWORD *) SourceBits;
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
|
||||
{
|
||||
*Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
|
||||
Dest32 = (DWORD *) DestBits;
|
||||
Source32 = (DWORD *) SourceBits;
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest32 = (DWORD *) DestBits + (DestWidth - 1);
|
||||
Source32 = (DWORD *) SourceBits + (DestWidth - 1);
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
*Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
|
||||
}
|
||||
}
|
||||
SourceBits += BltInfo->SourceSurface->lDelta;
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y
|
||||
+ DestHeight - 1) * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta)
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
{
|
||||
Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
|
||||
{
|
||||
*Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
|
||||
Dest32 = (DWORD *) DestBits;
|
||||
Source32 = (DWORD *) SourceBits;
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest32 = (DWORD *) DestBits + (DestWidth - 1);
|
||||
Source32 = (DWORD *) SourceBits + (DestWidth - 1);
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
*Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
|
||||
}
|
||||
}
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
SourceBits += BltInfo->SourceSurface->lDelta;
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
/* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */
|
||||
BOOL TopToBottomDone = FALSE;
|
||||
|
||||
/* No need to flip a LeftToRight bitmap only one pixel wide */
|
||||
if ((bLeftToRight) && (DestWidth > 1))
|
||||
{
|
||||
if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
|
||||
DPRINT("Flip is bLeftToRight.\n");
|
||||
|
||||
/* Allocate enough pixels for a row in DWORD's */
|
||||
DWORD *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
(DestWidth + 1) * 4, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
Dest32 = (DWORD *) DestBits;
|
||||
Source32 = (DWORD *) SourceBits;
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
|
||||
}
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This sets SourceBits to the bottom line */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y + DestHeight - 1)
|
||||
* BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets DestBits to the bottom line */
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ (BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
{
|
||||
|
||||
/* Set Dest32 to right pixel */
|
||||
Dest32 = (DWORD *) DestBits + (DestWidth - 1);
|
||||
Source32 = (DWORD *) SourceBits;
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Store pixels from left to right */
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
store[Index] = *Source32++;
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Copy stored dat to pixels from right to left */
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
*Dest32-- = store[Index];
|
||||
Index++;
|
||||
}
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
TopToBottomDone = TRUE;
|
||||
}
|
||||
|
||||
/* Top to Botoom Handling if bitmap more than one pixel high */
|
||||
if ((bTopToBottom) && (DestHeight > 1))
|
||||
{
|
||||
/* Note: It is very important that this code remain optimized for time used.
|
||||
* Otherwise you will have random crashes in ReactOS that are undesirable.
|
||||
* For an example of this just try executing the code here two times.
|
||||
*/
|
||||
|
||||
DPRINT("Flip is bTopToBottom.\n");
|
||||
|
||||
/* Allocate enough pixels for a row in DWORD's */
|
||||
DWORD *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
(DestWidth + 1) * 4, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This set DestBitsT to the top line */
|
||||
DestBitsT = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ ((BltInfo->DestRect.top) * BltInfo->DestSurface->lDelta)
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
|
||||
/* This sets DestBitsB to the bottom line */
|
||||
DestBitsB = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ (BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
|
||||
/* The TopToBottomDone flag indicates that we are flipping for bTopToBottom and bLeftToRight
|
||||
* and have already completed the bLeftToRight. So we will lose our first flip output
|
||||
* unless we work with its output which is at the destination site. So in this case
|
||||
* our new Source becomes the previous outputs Destination.
|
||||
* Also in we use the same logic when we have corrected for negative lDelta's above
|
||||
* and already completed a flip from Source to Destination for the first step
|
||||
*/
|
||||
|
||||
if (TopToBottomDone || blDeltaAdjustDone)
|
||||
{
|
||||
/* This sets SourceBitsB to the bottom line */
|
||||
SourceBitsB = DestBitsB;
|
||||
|
||||
/* This sets SourceBitsT to the top line */
|
||||
SourceBitsT = DestBitsT;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
|
||||
{
|
||||
*Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
|
||||
}
|
||||
/* This sets SourceBitsB to the bottom line */
|
||||
SourceBitsB = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y + DestHeight - 1)
|
||||
* BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets SourceBitsT to the top line */
|
||||
SourceBitsT = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
}
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
|
||||
/* Overlaps and Vertical flips do not mix well. So we test for this and handle it
|
||||
* by using two operations. First we just do a copy of the source to the destination.
|
||||
* Then we do a flip in place at the destination location and we are done.
|
||||
*/
|
||||
if ((BltInfo->SourcePoint.y != BltInfo->DestRect.top) && // The values are not equal and
|
||||
(abs(BltInfo->SourcePoint.y - BltInfo->DestRect.top) < (DestHeight + 2)) && // they are NOT seperated by > DestHeight
|
||||
(BltInfo->SourceSurface->pvScan0 == BltInfo->DestSurface->pvScan0)) // and same surface (probably screen)
|
||||
{
|
||||
DPRINT("Flips Need Adjustments, so do move here.\n");
|
||||
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
/* SourceBits points to top-left pixel for lDelta < 0 and bottom-left for lDelta > 0 */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * DestWidth);
|
||||
SourceBits += BltInfo->SourceSurface->lDelta;
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SourceBits points to bottom-left pixel for lDelta < 0 and top-left for lDelta > 0 */
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
|
||||
+ ((BltInfo->SourcePoint.y
|
||||
+ DestHeight - 1) * BltInfo->SourceSurface->lDelta)
|
||||
+ 4 * BltInfo->SourcePoint.x;
|
||||
/* SourceBits points to bottom-left pixel for lDelta < 0 and top-left for lDelta > 0 */
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
|
||||
+ ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta)
|
||||
+ 4 * BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
{
|
||||
RtlMoveMemory(DestBits, SourceBits, 4 * DestWidth);
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
DestBits -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
}
|
||||
|
||||
/* This sets SourceBitsB to the bottom line */
|
||||
SourceBitsB = DestBitsB;
|
||||
|
||||
/* This sets SourceBitsT to the top line */
|
||||
SourceBitsT = DestBitsT;
|
||||
}
|
||||
|
||||
/* Vertical Flip code starts here */
|
||||
for (j = 0; j < DestHeight / 2 ; j++)
|
||||
{
|
||||
/* Store bottom row of Source pixels */
|
||||
RtlMoveMemory(store, SourceBitsB, 4 * DestWidth);
|
||||
|
||||
/* Copy top Source row to bottom Destination row overwriting it */
|
||||
RtlMoveMemory(DestBitsB, SourceBitsT, 4 * DestWidth);
|
||||
|
||||
/* Copy stored bottom row of Source pixels to Destination top row of pixels */
|
||||
RtlMoveMemory(DestBitsT, store, 4 * DestWidth);
|
||||
|
||||
/* Index top rows down and bottom rows up */
|
||||
SourceBitsT += BltInfo->SourceSurface->lDelta;
|
||||
SourceBitsB -= BltInfo->SourceSurface->lDelta;
|
||||
|
||||
DestBitsT += BltInfo->DestSurface->lDelta;
|
||||
DestBitsB -= BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
if (DestHeight % 2)
|
||||
{
|
||||
/* If we had an odd number of lines we handle the center one here */
|
||||
DPRINT("Handling Top To Bottom with Odd Number of lines.\n");
|
||||
RtlMoveMemory(DestBitsB, SourceBitsT, 4 * DestWidth);
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
|
||||
DPRINT1("DIB_32BPP_BitBltSrcCopy: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -352,7 +770,7 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||
register NICEPIXEL32 DstPixel, SrcPixel;
|
||||
UCHAR Alpha, SrcBpp;
|
||||
|
||||
DPRINT("DIB_32BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||
DPRINT("DIB_32BPP_AlphaBlend: SourceRect: (%d,%d)-(%d,%d), DestRect: (%d,%d)-(%d,%d)\n",
|
||||
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
|
@ -32,6 +32,9 @@ DIB_32BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
|
||||
{
|
||||
ULONG DestY;
|
||||
|
||||
/* Make WellOrdered by making top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
|
||||
{
|
||||
DIB_32BPP_HLine (DestSurface, DestRect->left, DestRect->right, DestY, color);
|
||||
|
@ -4,14 +4,17 @@
|
||||
* FILE: win32ss/gdi/dib/dib4bpp.c
|
||||
* PURPOSE: Device Independant Bitmap functions, 4bpp
|
||||
* PROGRAMMERS: Jason Filby
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
|
||||
#include <win32k.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define DEC_OR_INC(var, decTrue, amount) \
|
||||
((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
|
||||
|
||||
VOID
|
||||
DIB_4BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
|
||||
{
|
||||
@ -63,6 +66,24 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
PBYTE SourceBits_24BPP, SourceLine_24BPP;
|
||||
PBYTE DestBits, DestLine, SourceBits_8BPP, SourceLine_8BPP;
|
||||
PBYTE SourceBits, SourceLine;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
DPRINT("DIB_4BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
|
||||
BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
/* Get back left to right flip here */
|
||||
bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right);
|
||||
|
||||
/* Check for top to bottom flip needed. */
|
||||
bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
|
||||
|
||||
/* Make WellOrdered with top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(&BltInfo->DestRect);
|
||||
|
||||
DPRINT("BPP is '%d/%d' & BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourceSurface->iBitmapFormat, BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 +
|
||||
(BltInfo->DestRect.left >> 1) +
|
||||
@ -71,12 +92,30 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
switch (BltInfo->SourceSurface->iBitmapFormat)
|
||||
{
|
||||
case BMF_1BPP:
|
||||
DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets sy to the bottom line */
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
|
||||
@ -87,64 +126,129 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
{
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_4BPP:
|
||||
DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets sy to the bottom line */
|
||||
sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1)
|
||||
* BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
if (NULL != BltInfo->XlateSourceToDest)
|
||||
{
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy)));
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j,
|
||||
XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
|
||||
DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j,
|
||||
DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_8BPP:
|
||||
SourceBits_8BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
DPRINT("8BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceBits_8BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceBits to the bottom line */
|
||||
SourceBits_8BPP = (PBYTE)((LONG_PTR)SourceBits_8BPP +
|
||||
((BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) *
|
||||
BltInfo->SourceSurface->lDelta));
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceLine_8BPP = SourceBits_8BPP;
|
||||
DestLine = DestBits;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits_8BPP to the rightmost pixel */
|
||||
SourceBits_8BPP += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
f2 = BltInfo->DestRect.left & 1;
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*DestLine = (*DestLine & notmask[f2]) |
|
||||
(BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_8BPP)) << ((4 * (1 - f2))));
|
||||
if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
|
||||
SourceLine_8BPP++;
|
||||
if (f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
|
||||
DEC_OR_INC(SourceLine_8BPP, bLeftToRight, 1);
|
||||
}
|
||||
|
||||
SourceBits_8BPP += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceBits_8BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_16BPP:
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
|
||||
DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
DPRINT("BMF_16BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
2 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) *
|
||||
BltInfo->SourceSurface->lDelta;;
|
||||
}
|
||||
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 2;
|
||||
}
|
||||
|
||||
DestBits = DestLine;
|
||||
f2 = BltInfo->DestRect.left & 1;
|
||||
|
||||
@ -154,16 +258,32 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
*DestBits = (*DestBits & notmask[f2]) |
|
||||
(BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor)) << ((4 * (1 - f2))));
|
||||
if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; }
|
||||
SourceBits += 2;
|
||||
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 2);
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_24BPP:
|
||||
SourceBits_24BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x * 3;
|
||||
|
||||
DPRINT("24BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceBits_24BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
BltInfo->SourcePoint.x * 3;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceBits_24BPP += BltInfo->SourceSurface->lDelta *
|
||||
(BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
@ -171,6 +291,12 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
DestLine = DestBits;
|
||||
f2 = BltInfo->DestRect.left & 1;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits_24BPP to the rightmost pixel */
|
||||
SourceLine_24BPP += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 3;
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = (*(SourceLine_24BPP + 2) << 0x10) +
|
||||
@ -179,22 +305,40 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
*DestLine = (*DestLine & notmask[f2]) |
|
||||
(BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor)) << ((4 * (1 - f2))));
|
||||
if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
|
||||
SourceLine_24BPP+=3;
|
||||
DEC_OR_INC(SourceLine_24BPP, bLeftToRight, 3);
|
||||
}
|
||||
|
||||
SourceBits_24BPP += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceBits_24BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestBits += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_32BPP:
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) +
|
||||
4 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
|
||||
}
|
||||
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4;
|
||||
}
|
||||
|
||||
f2 = BltInfo->DestRect.left & 1;
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
@ -203,16 +347,18 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
*DestBits = (*DestBits & notmask[f2]) |
|
||||
(BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor)) << ((4 * (1 - f2))));
|
||||
if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; }
|
||||
SourceBits += 4;
|
||||
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 4);
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
|
||||
DbgPrint("DIB_4BPP_BitBltSrcCopy: Unhandled Source BPP: %u\n",
|
||||
BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
|
||||
return FALSE;
|
||||
}
|
||||
return(TRUE);
|
||||
@ -290,7 +436,8 @@ DIB_4BPP_BitBlt(PBLTINFO BltInfo)
|
||||
|
||||
if (BltInfo->PatternSurface)
|
||||
{
|
||||
Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
|
||||
Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface,
|
||||
(DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
|
||||
}
|
||||
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
|
||||
@ -339,7 +486,8 @@ DIB_4BPP_BitBlt(PBLTINFO BltInfo)
|
||||
}
|
||||
if (BltInfo->PatternSurface)
|
||||
{
|
||||
Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
|
||||
Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface,
|
||||
(DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
|
||||
}
|
||||
DIB_4BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
|
||||
}
|
||||
@ -361,6 +509,9 @@ DIB_4BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
|
||||
{
|
||||
LONG DestY;
|
||||
|
||||
/* Make WellOrdered by making top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
for (DestY = DestRect->top; DestY < DestRect->bottom; DestY++)
|
||||
{
|
||||
DIB_4BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
|
||||
|
@ -6,6 +6,7 @@
|
||||
* PROGRAMMERS: Jason Filby
|
||||
* Thomas Bluemel
|
||||
* Gregor Anich
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -13,6 +14,9 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define DEC_OR_INC(var, decTrue, amount) \
|
||||
((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
|
||||
|
||||
VOID
|
||||
DIB_8BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
|
||||
{
|
||||
@ -57,18 +61,56 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
LONG i, j, sx, sy, xColor, f1;
|
||||
PBYTE SourceBits, DestBits, SourceLine, DestLine;
|
||||
PBYTE SourceBits_4BPP, SourceLine_4BPP;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
DPRINT("DIB_8BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
|
||||
BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
|
||||
|
||||
/* Get back left to right flip here */
|
||||
bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right);
|
||||
|
||||
/* Check for top to bottom flip needed. */
|
||||
bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
|
||||
|
||||
DPRINT("bTopToBottom is '%d' and bLeftToRight is '%d'.\n", bTopToBottom, bLeftToRight);
|
||||
|
||||
/* Make WellOrdered by making top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(&BltInfo->DestRect);
|
||||
|
||||
DPRINT("BPP is '%d' & BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n",
|
||||
BltInfo->SourceSurface->iBitmapFormat, BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
|
||||
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
|
||||
|
||||
switch(BltInfo->SourceSurface->iBitmapFormat)
|
||||
{
|
||||
case BMF_1BPP:
|
||||
DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
/* This sets sy to the top line */
|
||||
sy = BltInfo->SourcePoint.y;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets sy to the bottom line */
|
||||
sy += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
{
|
||||
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
|
||||
@ -79,19 +121,36 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
{
|
||||
DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
|
||||
}
|
||||
sx++;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
sy++;
|
||||
DEC_OR_INC(sy, bTopToBottom, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_4BPP:
|
||||
DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
/* This sets SourceBits_4BPP to the top line */
|
||||
SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceBits_4BPP to the bottom line */
|
||||
SourceBits_4BPP += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
|
||||
}
|
||||
|
||||
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceLine_4BPP = SourceBits_4BPP;
|
||||
sx = BltInfo->SourcePoint.x;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets sx to the rightmost pixel */
|
||||
sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
}
|
||||
|
||||
f1 = sx & 1;
|
||||
|
||||
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
|
||||
@ -99,19 +158,35 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
|
||||
(*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
|
||||
DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
|
||||
if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
|
||||
sx++;
|
||||
}
|
||||
if(f1 == 1)
|
||||
{
|
||||
DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1);
|
||||
f1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
f1 = 1;
|
||||
}
|
||||
|
||||
SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(sx, bLeftToRight, 1);
|
||||
}
|
||||
DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_8BPP:
|
||||
if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
|
||||
DPRINT("8BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
if ((BltInfo->XlateSourceToDest == NULL ||
|
||||
(BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) &&
|
||||
(!bTopToBottom && !bLeftToRight))
|
||||
{
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
DPRINT("BltInfo->DestRect.top < BltInfo->SourcePoint.y.\n");
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
@ -122,6 +197,7 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("BltInfo->DestRect.top >= BltInfo->SourcePoint.y.\n");
|
||||
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
@ -134,8 +210,14 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("XO_TRIVIAL is NOT TRUE or we have flips.\n");
|
||||
|
||||
if (!bTopToBottom && !bLeftToRight)
|
||||
/* **Note: Indent is purposefully less than desired to keep reviewable differences to a minimum for PR** */
|
||||
{
|
||||
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
|
||||
{
|
||||
DPRINT("Dest.top < SourcePoint.y.\n");
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
DestLine = DestBits;
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -152,6 +234,7 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Dest.top >= SourcePoint.y.\n");
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
|
||||
DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
|
||||
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
|
||||
@ -167,56 +250,244 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */
|
||||
BOOL OneDone = FALSE;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
DPRINT("Flip is bLeftToRight.\n");
|
||||
|
||||
/* Allocate enough pixels for a row in BYTE's */
|
||||
BYTE *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left + 1, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
WORD Index;
|
||||
|
||||
/* This sets SourceLine to the top line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
(BltInfo->SourcePoint.y *
|
||||
BltInfo->SourceSurface->lDelta) +
|
||||
BltInfo->SourcePoint.x;
|
||||
|
||||
/* This set the DestLine to the top line */
|
||||
DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 +
|
||||
(BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) +
|
||||
BltInfo->DestRect.left;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
|
||||
|
||||
Index = 0;
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
store[Index] = (BYTE)XLATEOBJ_iXlate(
|
||||
BltInfo->XlateSourceToDest,
|
||||
*SourceBits);
|
||||
SourceBits--;
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
*DestBits = store[Index];
|
||||
DestBits++;
|
||||
Index++;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
OneDone = TRUE;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
DPRINT("Flip is bTopToBottom.\n");
|
||||
|
||||
DWORD Index;
|
||||
|
||||
/* Allocate enough pixels for a column in BYTE's */
|
||||
BYTE *store = ExAllocatePoolWithTag(NonPagedPool,
|
||||
BltInfo->DestRect.bottom - BltInfo->DestRect.top + 1, TAG_DIB);
|
||||
if (store == NULL)
|
||||
{
|
||||
DPRINT1("Storage Allocation Failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The OneDone flag indicates that we are flipping for bTopToBottom and bLeftToRight
|
||||
* and have already completed the bLeftToRight. So we will lose our first flip output
|
||||
* unless we work with its output which is at the destination site. So in this case
|
||||
* our new Source becomes the previous outputs Destination. */
|
||||
|
||||
if (OneDone)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line of our previous destination */
|
||||
SourceLine = (PBYTE)BltInfo->DestSurface->pvScan0 +
|
||||
(BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left +
|
||||
(BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
|
||||
((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1)
|
||||
* BltInfo->SourceSurface->lDelta) +
|
||||
BltInfo->SourcePoint.x;
|
||||
}
|
||||
|
||||
/* This set the DestLine to the top line */
|
||||
DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 +
|
||||
(BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) +
|
||||
BltInfo->DestRect.left;
|
||||
|
||||
/* Read columns */
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
|
||||
DestBits = DestLine;
|
||||
SourceBits = SourceLine;
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Read up the column and store the pixels */
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
store[Index] = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
|
||||
/* Go up a line */
|
||||
SourceBits -= BltInfo->SourceSurface->lDelta;
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* Get the stored pixel and copy then down the column */
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
*DestBits = store[Index];
|
||||
/* Go down a line */
|
||||
DestBits += BltInfo->SourceSurface->lDelta;
|
||||
Index++;
|
||||
}
|
||||
/* Index to next column */
|
||||
SourceLine += 1;
|
||||
DestLine += 1;
|
||||
}
|
||||
ExFreePoolWithTag(store, TAG_DIB);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_16BPP:
|
||||
DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
DPRINT("BMF_16BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;;
|
||||
}
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 2;
|
||||
}
|
||||
DestBits = DestLine;
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = *((PWORD) SourceBits);
|
||||
*DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
|
||||
SourceBits += 2;
|
||||
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 2);
|
||||
DestBits += 1;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_24BPP:
|
||||
DPRINT("24BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
|
||||
BltInfo->DestRect.left, BltInfo->DestRect.top,
|
||||
BltInfo->DestRect.right, BltInfo->DestRect.bottom,
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
|
||||
DestLine = DestBits;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
|
||||
}
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
{
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets the SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 3;
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = (*(SourceBits + 2) << 0x10) +
|
||||
(*(SourceBits + 1) << 0x08) +
|
||||
(*(SourceBits));
|
||||
*DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
|
||||
SourceBits += 3;
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 3);
|
||||
DestBits += 1;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_32BPP:
|
||||
DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n",
|
||||
BltInfo->DestRect.right - BltInfo->DestRect.left);
|
||||
|
||||
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
/* This sets SourceLine to the bottom line */
|
||||
SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
|
||||
}
|
||||
DestLine = DestBits;
|
||||
|
||||
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
|
||||
@ -224,15 +495,21 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
|
||||
SourceBits = SourceLine;
|
||||
DestBits = DestLine;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
/* This sets SourceBits to the rightmost pixel */
|
||||
SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4;
|
||||
}
|
||||
|
||||
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
|
||||
{
|
||||
xColor = *((PDWORD) SourceBits);
|
||||
*DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
|
||||
SourceBits += 4;
|
||||
|
||||
DEC_OR_INC(SourceBits, bLeftToRight, 4);
|
||||
DestBits += 1;
|
||||
}
|
||||
|
||||
SourceLine += BltInfo->SourceSurface->lDelta;
|
||||
DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
|
||||
DestLine += BltInfo->DestSurface->lDelta;
|
||||
}
|
||||
break;
|
||||
@ -250,6 +527,10 @@ BOOLEAN
|
||||
DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
|
||||
{
|
||||
LONG DestY;
|
||||
|
||||
/* Make WellOrdered by making top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
|
||||
{
|
||||
DIB_8BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
|
||||
|
@ -6,6 +6,7 @@
|
||||
* PROGRAMMERS: Magnus Olsen
|
||||
* Evgeniy Boltik
|
||||
* Gregor Schneider
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -47,25 +48,46 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
|
||||
|
||||
BOOL UsesSource = ROP4_USES_SOURCE(ROP);
|
||||
BOOL UsesPattern = ROP4_USES_PATTERN(ROP);
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
ASSERT(IS_VALID_ROP4(ROP));
|
||||
|
||||
fnDest_GetPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_GetPixel;
|
||||
fnDest_PutPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_PutPixel;
|
||||
|
||||
DPRINT("Dest BPP: %u, dstRect: (%d,%d)-(%d,%d)\n",
|
||||
DPRINT("Dest BPP: %u, DestRect: (%d,%d)-(%d,%d)\n",
|
||||
BitsPerFormat(DestSurf->iBitmapFormat), DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
DstHeight = DestRect->bottom - DestRect->top;
|
||||
DstWidth = DestRect->right - DestRect->left;
|
||||
SrcHeight = SourceRect->bottom - SourceRect->top;
|
||||
SrcWidth = SourceRect->right - SourceRect->left;
|
||||
|
||||
/* Here we do the tests and set our conditions */
|
||||
if (((SrcWidth < 0) && (DstWidth < 0)) || ((SrcWidth >= 0) && (DstWidth >= 0)))
|
||||
bLeftToRight = FALSE;
|
||||
else
|
||||
bLeftToRight = TRUE;
|
||||
|
||||
if (((SrcHeight < 0) && (DstHeight < 0)) || ((SrcHeight >= 0) && (DstHeight >= 0)))
|
||||
bTopToBottom = FALSE;
|
||||
else
|
||||
bTopToBottom = TRUE;
|
||||
|
||||
/* Make Well Ordered to start */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
|
||||
if (UsesSource)
|
||||
{
|
||||
SourceCy = SourceSurf->sizlBitmap.cy;
|
||||
fnSource_GetPixel = DibFunctionsForBitmapFormat[SourceSurf->iBitmapFormat].DIB_GetPixel;
|
||||
DPRINT("Source BPP: %u, srcRect: (%d,%d)-(%d,%d)\n",
|
||||
DPRINT("Source BPP: %u, SourceRect: (%d,%d)-(%d,%d)\n",
|
||||
BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
|
||||
}
|
||||
|
||||
if (MaskSurf)
|
||||
{
|
||||
DPRINT("MaskSurf is not NULL.\n");
|
||||
fnMask_GetPixel = DibFunctionsForBitmapFormat[MaskSurf->iBitmapFormat].DIB_GetPixel;
|
||||
MaskCy = MaskSurf->sizlBitmap.cy;
|
||||
}
|
||||
@ -87,9 +109,11 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
|
||||
default:
|
||||
xxBPPMask = 0xFFFFFFFF;
|
||||
}
|
||||
DPRINT("xxBPPMask is 0x%x.\n", xxBPPMask);
|
||||
|
||||
if (UsesPattern)
|
||||
{
|
||||
DPRINT("UsesPattern is not NULL.\n");
|
||||
if (PatternSurface)
|
||||
{
|
||||
PatternY = (DestRect->top - BrushOrigin->y) % PatternSurface->sizlBitmap.cy;
|
||||
@ -106,6 +130,12 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
|
||||
}
|
||||
}
|
||||
|
||||
if (PatternSurface)
|
||||
{
|
||||
DPRINT("PatternSurface is not NULL.\n");
|
||||
}
|
||||
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
for (DesY = DestRect->top; DesY < DestRect->bottom; DesY++)
|
||||
{
|
||||
@ -118,7 +148,16 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
|
||||
}
|
||||
}
|
||||
if (UsesSource)
|
||||
sy = SourceRect->top+(DesY - DestRect->top) * SrcHeight / DstHeight;
|
||||
{
|
||||
if (bTopToBottom)
|
||||
{
|
||||
sy = SourceRect->bottom-(DesY - DestRect->top) * SrcHeight / DstHeight; // flips about the x-axis
|
||||
}
|
||||
else
|
||||
{
|
||||
sy = SourceRect->top+(DesY - DestRect->top) * SrcHeight / DstHeight;
|
||||
}
|
||||
}
|
||||
|
||||
for (DesX = DestRect->left; DesX < DestRect->right; DesX++)
|
||||
{
|
||||
@ -126,7 +165,14 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
|
||||
|
||||
if (fnMask_GetPixel)
|
||||
{
|
||||
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
|
||||
if (bLeftToRight)
|
||||
{
|
||||
sx = SourceRect->right - (DesX - DestRect->left) * SrcWidth / DstWidth; // flips about the y-axis
|
||||
}
|
||||
else
|
||||
{
|
||||
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
|
||||
}
|
||||
if (sx < 0 || sy < 0 ||
|
||||
MaskSurf->sizlBitmap.cx < sx || MaskCy < sy ||
|
||||
fnMask_GetPixel(MaskSurf, sx, sy) != 0)
|
||||
@ -137,7 +183,14 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
|
||||
|
||||
if (UsesSource && CanDraw)
|
||||
{
|
||||
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
|
||||
if (bLeftToRight)
|
||||
{
|
||||
sx = SourceRect->right-(DesX - DestRect->left) * SrcWidth / DstWidth; // flips about the y-axis
|
||||
}
|
||||
else
|
||||
{
|
||||
sx = SourceRect->left + (DesX - DestRect->left) * SrcWidth / DstWidth;
|
||||
}
|
||||
if (sx >= 0 && sy >= 0 &&
|
||||
SourceSurf->sizlBitmap.cx > sx && SourceCy > sy)
|
||||
{
|
||||
|
@ -3,8 +3,13 @@
|
||||
* PROJECT: ReactOS Win32k subsystem
|
||||
* PURPOSE: GDI BitBlt Functions
|
||||
* FILE: win32ss/gdi/eng/bitblt.c
|
||||
* PROGRAMER: Jason Filby
|
||||
* PROGRAMERS: Jason Filby
|
||||
* Timo Kreuzer
|
||||
* Doug Lyons
|
||||
*
|
||||
* WARNING: Modify this file with extreme caution. It is very sensitive to timing changes.
|
||||
* Adding code can cause the system to show a Fatal Exception Error and fail to boot!.
|
||||
* This is especially true in CallDibBitBlt, IntEngBitBlt and EngBitBlt (even DPRINT's).
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -255,6 +260,12 @@ CallDibBitBlt(SURFOBJ* OutputObj,
|
||||
psoPattern = NULL;
|
||||
}
|
||||
|
||||
/* Make WellOrdered with top < bottom and left < right */
|
||||
RECTL_vMakeWellOrdered(&BltInfo.DestRect);
|
||||
|
||||
DPRINT("CallDibBitBlt: BltInfo.DestRect: (%d,%d)-(%d,%d)\n",
|
||||
BltInfo.DestRect.left, BltInfo.DestRect.top, BltInfo.DestRect.right, BltInfo.DestRect.bottom);
|
||||
|
||||
Result = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBlt(&BltInfo);
|
||||
|
||||
return Result;
|
||||
@ -344,10 +355,30 @@ EngBitBlt(
|
||||
ULONG Direction;
|
||||
BOOL UsesSource, UsesMask;
|
||||
POINTL AdjustedBrushOrigin;
|
||||
LONG lTmp;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
UsesSource = ROP4_USES_SOURCE(rop4);
|
||||
UsesMask = ROP4_USES_MASK(rop4);
|
||||
|
||||
if (prclTrg->left > prclTrg->right)
|
||||
{
|
||||
bLeftToRight = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bLeftToRight = FALSE;
|
||||
}
|
||||
|
||||
if (prclTrg->top > prclTrg->bottom)
|
||||
{
|
||||
bTopToBottom = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bTopToBottom = FALSE;
|
||||
}
|
||||
|
||||
if (rop4 == ROP4_NOOP)
|
||||
{
|
||||
/* Copy destination onto itself: nop */
|
||||
@ -359,6 +390,12 @@ EngBitBlt(
|
||||
OutputRect = *prclTrg;
|
||||
RECTL_vMakeWellOrdered(&OutputRect);
|
||||
|
||||
DPRINT("EngBitBlt: prclTrg: (%d,%d)-(%d,%d)\n",
|
||||
prclTrg->left, prclTrg->top, prclTrg->right, prclTrg->bottom);
|
||||
|
||||
DPRINT("EngBitBlt: OutputRect: (%d,%d)-(%d,%d)\n",
|
||||
OutputRect.left, OutputRect.top, OutputRect.right, OutputRect.bottom);
|
||||
|
||||
if (UsesSource)
|
||||
{
|
||||
if (!psoSrc || !pptlSrc)
|
||||
@ -498,6 +535,21 @@ EngBitBlt(
|
||||
switch (clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
/* Fix up OutputRect here */
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = OutputRect.left;
|
||||
OutputRect.left = OutputRect.right;
|
||||
OutputRect.right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = OutputRect.top;
|
||||
OutputRect.top = OutputRect.bottom;
|
||||
OutputRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
Ret = (*BltRectFunc)(OutputObj,
|
||||
InputObj,
|
||||
psoMask,
|
||||
@ -622,6 +674,8 @@ IntEngBitBlt(
|
||||
RECTL rclSrcClipped;
|
||||
POINTL ptlBrush;
|
||||
PFN_DrvBitBlt pfnBitBlt;
|
||||
LONG lTmp;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
|
||||
/* Sanity checks */
|
||||
ASSERT(IS_VALID_ROP4(Rop4));
|
||||
@ -629,6 +683,9 @@ IntEngBitBlt(
|
||||
|
||||
psurfTrg = CONTAINING_RECORD(psoTrg, SURFACE, SurfObj);
|
||||
|
||||
bLeftToRight = prclTrg->left > prclTrg->right;
|
||||
bTopToBottom = prclTrg->top > prclTrg->bottom;
|
||||
|
||||
/* Get the target rect and make it well ordered */
|
||||
rclClipped = *prclTrg;
|
||||
RECTL_vMakeWellOrdered(&rclClipped);
|
||||
@ -721,6 +778,24 @@ IntEngBitBlt(
|
||||
pfnBitBlt = EngBitBlt;
|
||||
}
|
||||
|
||||
/* rclClipped needs to be modified in accordance with flips here */
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = rclClipped.left;
|
||||
rclClipped.left = rclClipped.right;
|
||||
rclClipped.right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = rclClipped.top;
|
||||
rclClipped.top = rclClipped.bottom;
|
||||
rclClipped.bottom = lTmp;
|
||||
}
|
||||
|
||||
DPRINT("About to call EngBitBlt: rclClipped: (%d,%d)-(%d,%d)\n",
|
||||
rclClipped.left, rclClipped.top, rclClipped.right, rclClipped.bottom);
|
||||
|
||||
bResult = pfnBitBlt(psoTrg,
|
||||
psoSrc,
|
||||
psoMask,
|
||||
|
@ -3,7 +3,8 @@
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: GDI EngCopyBits Function
|
||||
* FILE: win32ss/gdi/eng/copybits.c
|
||||
* PROGRAMER: Jason Filby
|
||||
* PROGRAMERS: Jason Filby
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -32,6 +33,30 @@ EngCopyBits(
|
||||
SURFACE *psurfSource;
|
||||
RECTL rclDest = *DestRect;
|
||||
POINTL ptlSrc = *SourcePoint;
|
||||
LONG lTmp;
|
||||
BOOL bTopToBottom;
|
||||
|
||||
DPRINT("Entering EngCopyBits with SourcePoint (%d,%d) and DestRect (%d,%d)-(%d,%d).\n",
|
||||
SourcePoint->x, SourcePoint->y, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
DPRINT("psoSource cx/cy is %d/%d and psoDest cx/cy is %d/%d.\n",
|
||||
psoSource->sizlBitmap.cx, psoSource->sizlBitmap.cy, psoDest->sizlBitmap.cx, psoDest->sizlBitmap.cy);
|
||||
|
||||
/* Retrieve Top Down/flip here and then make Well-Ordered again */
|
||||
if (DestRect->top > DestRect->bottom)
|
||||
{
|
||||
bTopToBottom = TRUE;
|
||||
lTmp = DestRect->top;
|
||||
DestRect->top = DestRect->bottom;
|
||||
DestRect->bottom = lTmp;
|
||||
rclDest = *DestRect;
|
||||
}
|
||||
else
|
||||
{
|
||||
bTopToBottom = FALSE;
|
||||
}
|
||||
|
||||
DPRINT("bTopToBottom is '%d'.\n", bTopToBottom);
|
||||
|
||||
ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL);
|
||||
|
||||
@ -113,24 +138,42 @@ EngCopyBits(
|
||||
switch (clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
DPRINT("DC_TRIVIAL.\n");
|
||||
BltInfo.DestRect = *DestRect;
|
||||
BltInfo.SourcePoint = *SourcePoint;
|
||||
|
||||
/* Now we set the Dest Rect top and bottom based on Top Down/flip */
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = BltInfo.DestRect.top;
|
||||
BltInfo.DestRect.top = BltInfo.DestRect.bottom;
|
||||
BltInfo.DestRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
|
||||
break;
|
||||
|
||||
case DC_RECT:
|
||||
DPRINT("DC_RECT.\n");
|
||||
// Clip the blt to the clip rectangle
|
||||
RECTL_bIntersectRect(&BltInfo.DestRect, DestRect, &Clip->rclBounds);
|
||||
|
||||
BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
|
||||
BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
|
||||
|
||||
/* Now we set the Dest Rect top and bottom based on Top Down/flip */
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = BltInfo.DestRect.top;
|
||||
BltInfo.DestRect.top = BltInfo.DestRect.bottom;
|
||||
BltInfo.DestRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
|
||||
break;
|
||||
|
||||
case DC_COMPLEX:
|
||||
|
||||
DPRINT("DC_COMPLEX.\n");
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, 0);
|
||||
|
||||
do
|
||||
@ -149,6 +192,14 @@ EngCopyBits(
|
||||
BltInfo.SourcePoint.x = SourcePoint->x + BltInfo.DestRect.left - DestRect->left;
|
||||
BltInfo.SourcePoint.y = SourcePoint->y + BltInfo.DestRect.top - DestRect->top;
|
||||
|
||||
/* Now we set the Dest Rect top and bottom based on Top Down/flip */
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = BltInfo.DestRect.top;
|
||||
BltInfo.DestRect.top = BltInfo.DestRect.bottom;
|
||||
BltInfo.DestRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
if (!DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo))
|
||||
{
|
||||
ret = FALSE;
|
||||
|
@ -3,7 +3,8 @@
|
||||
* PROJECT: ReactOS Win32k subsystem
|
||||
* PURPOSE: GDI stretch blt functions
|
||||
* FILE: win32ss/gdi/eng/stretchblt.c
|
||||
* PROGRAMER: Jason Filby
|
||||
* PROGRAMERS: Jason Filby
|
||||
* Doug Lyons
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
@ -11,6 +12,21 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/***************************************************************************************************************************
|
||||
We want to receive and send the flip state along to existing functions without changing their parameter lists.
|
||||
So a way that we can do this is to use the DestRect to carry this information along with it.
|
||||
Since there are four values, we can use their relative positions (coordinates) to indicate the four flip conditions.
|
||||
if delta-x == 0 then there can be no Left-to-Right flip. If delta-y == 0 there can be no Top-to-Bottom flip.
|
||||
So we can set the four flip conditions based on BOOLEAN flags as follows:
|
||||
|
||||
We will use internal bits bTopToBottom and bLeftToRight as follows:
|
||||
|
||||
!bTopToBottom && !bLeftToRight means no flips therefore left < right and top < bottom (normal well-formed rectangle)
|
||||
bTopToBottom means there is a Top-To-Bottom flip therefore left < right and top > bottom
|
||||
bLeftToRight means there is a Left-To-Right flip therefore left > right and top < bottom
|
||||
bLeftToRight && bTopToBottom means both flips therefore left > right and top > bottom
|
||||
****************************************************************************************************************************/
|
||||
|
||||
typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
|
||||
SURFOBJ* InputObj,
|
||||
SURFOBJ* Mask,
|
||||
@ -38,6 +54,11 @@ CallDibStretchBlt(SURFOBJ* psoDest,
|
||||
SURFOBJ* psoPattern;
|
||||
BOOL bResult;
|
||||
|
||||
DPRINT("Entering CallDibStretchBlt: psoSource cx/cy (%d/%d), psoDest cx/cy (%d/%d) OutputRect: (%d,%d)-(%d,%d)\n",
|
||||
psoSource->sizlBitmap.cx, psoSource->sizlBitmap.cy,
|
||||
psoDest->sizlBitmap.cx, psoDest->sizlBitmap.cy,
|
||||
OutputRect->left, OutputRect->top, OutputRect->right, OutputRect->bottom);
|
||||
|
||||
if (BrushOrigin == NULL)
|
||||
{
|
||||
RealBrushOrigin.x = RealBrushOrigin.y = 0;
|
||||
@ -115,6 +136,35 @@ EngStretchBltROP(
|
||||
LONG SrcHeight;
|
||||
LONG SrcWidth;
|
||||
|
||||
LONG cxSrc, cySrc, cxDest, cyDest;
|
||||
BOOLEAN bLeftToRight, bTopToBottom;
|
||||
LONG lTmp;
|
||||
|
||||
DPRINT("Entering EngStretchBltROP: prclSrc: (%d/%d)-(%d/%d) prclDest: (%d,%d)-(%d,%d)\n",
|
||||
prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom,
|
||||
prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
|
||||
|
||||
cxSrc = prclSrc->right - prclSrc->left;
|
||||
cySrc = prclSrc->bottom - prclSrc->top;
|
||||
cxDest = prclDest->right - prclDest->left;
|
||||
cyDest = prclDest->bottom - prclDest->top;
|
||||
|
||||
/* Here we do the tests and set our conditions */
|
||||
if (((cxSrc < 0) && (cxDest < 0)) || ((cxSrc >= 0) && (cxDest >= 0)))
|
||||
bLeftToRight = FALSE;
|
||||
else
|
||||
bLeftToRight = TRUE;
|
||||
|
||||
if (((cySrc < 0) && (cyDest < 0)) || ((cySrc >= 0) && (cyDest >= 0)))
|
||||
bTopToBottom = FALSE;
|
||||
else
|
||||
bTopToBottom = TRUE;
|
||||
|
||||
/* Make Well Ordered to start */
|
||||
OutputRect = *prclDest;
|
||||
RECTL_vMakeWellOrdered(&OutputRect);
|
||||
*prclDest = OutputRect;
|
||||
|
||||
if (Rop4 == ROP4_NOOP)
|
||||
{
|
||||
/* Copy destination onto itself: nop */
|
||||
@ -237,9 +287,29 @@ EngStretchBltROP(
|
||||
DstWidth = OutputRect.right - OutputRect.left;
|
||||
SrcHeight = InputRect.bottom - InputRect.top;
|
||||
SrcWidth = InputRect.right - InputRect.left;
|
||||
|
||||
DPRINT("bLeftToRight is '%d' and bTopToBottom is '%d'.\n", bLeftToRight, bTopToBottom);
|
||||
|
||||
switch (clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = OutputRect.left;
|
||||
OutputRect.left = OutputRect.right;
|
||||
OutputRect.right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = OutputRect.top;
|
||||
OutputRect.top = OutputRect.bottom;
|
||||
OutputRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
DPRINT("About to call CallDibStretchBlt: OutputRect: (%d,%d)-(%d,%d)\n",
|
||||
OutputRect.left, OutputRect.top, OutputRect.right, OutputRect.bottom);
|
||||
|
||||
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
|
||||
ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
|
||||
pbo, &AdjustedBrushOrigin, Rop4);
|
||||
@ -256,6 +326,24 @@ EngStretchBltROP(
|
||||
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
|
||||
InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
|
||||
InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = CombinedRect.left;
|
||||
CombinedRect.left = CombinedRect.right;
|
||||
CombinedRect.right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = CombinedRect.top;
|
||||
CombinedRect.top = CombinedRect.bottom;
|
||||
CombinedRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
DPRINT("About to call CallDibStretchBlt: CombinedRect: (%d,%d)-(%d,%d)\n",
|
||||
CombinedRect.left, CombinedRect.top, CombinedRect.right, CombinedRect.bottom);
|
||||
|
||||
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
|
||||
ColorTranslation,
|
||||
&CombinedRect,
|
||||
@ -301,6 +389,24 @@ EngStretchBltROP(
|
||||
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
|
||||
InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
|
||||
InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = CombinedRect.left;
|
||||
CombinedRect.left = CombinedRect.right;
|
||||
CombinedRect.right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = CombinedRect.top;
|
||||
CombinedRect.top = CombinedRect.bottom;
|
||||
CombinedRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
DPRINT("About to call CallDibStretchBlt: CombinedRect: (%d,%d)-(%d,%d)\n",
|
||||
CombinedRect.left, CombinedRect.top, CombinedRect.right, CombinedRect.bottom);
|
||||
|
||||
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
|
||||
ColorTranslation,
|
||||
&CombinedRect,
|
||||
@ -382,6 +488,18 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
RECTL OutputRect;
|
||||
BOOL UsesSource = ROP4_USES_SOURCE(Rop4);
|
||||
LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
|
||||
LONG lTmp, cxSrc, cySrc, cxDest, cyDest;
|
||||
BOOLEAN bTopToBottom, bLeftToRight;
|
||||
INT Case0000, Case0001, Case0010, Case0011;
|
||||
INT Case0100, Case0101, Case0110, Case0111;
|
||||
INT Case1000, Case1001, Case1010, Case1011;
|
||||
INT Case1100, Case1101, Case1110;
|
||||
|
||||
DPRINT("Source cx/cy (%d/%d) and Destination cx/cy (%d/%d).\n",
|
||||
psoSource->sizlBitmap.cx, psoSource->sizlBitmap.cy, psoDest->sizlBitmap.cx, psoDest->sizlBitmap.cy);
|
||||
|
||||
DPRINT("Source lDelta is '%d' and Destination lDelta is '%d'.\n",
|
||||
psoSource->lDelta, psoDest->lDelta);
|
||||
|
||||
ASSERT(psoDest);
|
||||
//ASSERT(psoSource); // FIXME!
|
||||
@ -390,17 +508,113 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
//ASSERT(!RECTL_bIsEmptyRect(SourceRect)); // FIXME!
|
||||
|
||||
/* If no clip object is given, use trivial one */
|
||||
if (!ClipRegion) ClipRegion = (CLIPOBJ *)&gxcoTrivial;
|
||||
if (!ClipRegion)
|
||||
{
|
||||
DPRINT("Using trivial clip region.\n");
|
||||
ClipRegion = (CLIPOBJ *)&gxcoTrivial;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("ClipRegion->rclBounds is (%d,%d)-(%d,%d).\n",
|
||||
ClipRegion->rclBounds.left, ClipRegion->rclBounds.top,
|
||||
ClipRegion->rclBounds.right, ClipRegion->rclBounds.bottom);
|
||||
}
|
||||
|
||||
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
|
||||
|
||||
/* Sanity check */
|
||||
ASSERT(IS_VALID_ROP4(Rop4));
|
||||
|
||||
cxSrc = SourceRect->right - SourceRect->left;
|
||||
cySrc = SourceRect->bottom - SourceRect->top;
|
||||
cxDest = DestRect->right - DestRect->left;
|
||||
cyDest = DestRect->bottom - DestRect->top;
|
||||
|
||||
Case1110 = ((cxDest > 0) && (cyDest > 0) && (cxSrc > 0) && (cySrc < 0));
|
||||
Case1101 = ((cxDest > 0) && (cyDest > 0) && (cxSrc < 0) && (cySrc > 0));
|
||||
Case1100 = ((cxDest > 0) && (cyDest > 0) && (cxSrc < 0) && (cySrc < 0));
|
||||
Case1011 = ((cxDest > 0) && (cyDest < 0) && (cxSrc > 0) && (cySrc > 0));
|
||||
Case1010 = ((cxDest > 0) && (cyDest < 0) && (cxSrc > 0) && (cySrc < 0));
|
||||
Case1001 = ((cxDest > 0) && (cyDest < 0) && (cxSrc < 0) && (cySrc > 0));
|
||||
Case1000 = ((cxDest > 0) && (cyDest < 0) && (cxSrc < 0) && (cySrc < 0));
|
||||
Case0111 = ((cxDest < 0) && (cyDest > 0) && (cxSrc > 0) && (cySrc > 0));
|
||||
Case0110 = ((cxDest < 0) && (cyDest > 0) && (cxSrc > 0) && (cySrc < 0));
|
||||
Case0101 = ((cxDest < 0) && (cyDest > 0) && (cxSrc < 0) && (cySrc > 0));
|
||||
Case0100 = ((cxDest < 0) && (cyDest > 0) && (cxSrc < 0) && (cySrc < 0));
|
||||
Case0011 = ((cxDest < 0) && (cyDest < 0) && (cxSrc > 0) && (cySrc > 0));
|
||||
Case0010 = ((cxDest < 0) && (cyDest < 0) && (cxSrc > 0) && (cySrc < 0));
|
||||
Case0001 = ((cxDest < 0) && (cyDest < 0) && (cxSrc < 0) && (cySrc > 0));
|
||||
Case0000 = ((cxDest < 0) && (cyDest < 0) && (cxSrc < 0) && (cySrc < 0));
|
||||
|
||||
/* Make DestRect & OutputRect Well Ordered to start */
|
||||
RECTL_vMakeWellOrdered(DestRect);
|
||||
OutputRect = *DestRect;
|
||||
|
||||
/* Here we do the tests and set our conditions */
|
||||
if (((cxSrc < 0) && (cxDest < 0)) || ((cxSrc >= 0) && (cxDest >= 0)))
|
||||
bLeftToRight = FALSE;
|
||||
else
|
||||
bLeftToRight = TRUE;
|
||||
|
||||
if (((cySrc < 0) && (cyDest < 0)) || ((cySrc >= 0) && (cyDest >= 0)))
|
||||
bTopToBottom = FALSE;
|
||||
else
|
||||
bTopToBottom = TRUE;
|
||||
|
||||
DPRINT("bTopToBottom is '%d' and bLeftToRight is '%d'.\n", bTopToBottom, bLeftToRight);
|
||||
|
||||
/* Check if source and dest size are equal */
|
||||
if (((DestRect->right - DestRect->left) == (SourceRect->right - SourceRect->left)) &&
|
||||
((DestRect->bottom - DestRect->top) == (SourceRect->bottom - SourceRect->top)))
|
||||
if ((abs(DestRect->right - DestRect->left) == abs(SourceRect->right - SourceRect->left)) &&
|
||||
(abs(DestRect->bottom - DestRect->top) == abs(SourceRect->bottom - SourceRect->top)))
|
||||
{
|
||||
DPRINT("source and dest size are equal.\n");
|
||||
|
||||
DPRINT("IntEngStretchBlt: dstRect: (%d,%d)-(%d,%d)\n",
|
||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
if (Case0000 || Case0001 || Case0010 || Case0011) // Destinations X & Y are both negative
|
||||
{
|
||||
lTmp = SourceRect->left;
|
||||
SourceRect->left = SourceRect->right;
|
||||
SourceRect->right = lTmp;
|
||||
|
||||
lTmp = SourceRect->top;
|
||||
SourceRect->top = SourceRect->bottom;
|
||||
SourceRect->bottom = lTmp;
|
||||
}
|
||||
|
||||
if (Case0100 || Case0101 || Case0110 || Case0111) // Destination X is negative and Y is positive
|
||||
{
|
||||
lTmp = SourceRect->left;
|
||||
SourceRect->left = SourceRect->right;
|
||||
SourceRect->right = lTmp;
|
||||
}
|
||||
|
||||
if (Case1000 || Case1001 || Case1010 || Case1011) // Destination X is positive and Y is negative
|
||||
{
|
||||
lTmp = SourceRect->top;
|
||||
SourceRect->top = SourceRect->bottom;
|
||||
SourceRect->bottom = lTmp;
|
||||
}
|
||||
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = DestRect->left;
|
||||
DestRect->left = DestRect->right;
|
||||
DestRect->right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = DestRect->top;
|
||||
DestRect->top = DestRect->bottom;
|
||||
DestRect->bottom = lTmp;
|
||||
}
|
||||
|
||||
DPRINT("Calling IntEngBitBlt: SourceRect (%d,%d)-(%d,%d) DestRect: (%d,%d)-(%d,%d)\n",
|
||||
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
/* Pass the request to IntEngBitBlt */
|
||||
return IntEngBitBlt(psoDest,
|
||||
psoSource,
|
||||
@ -415,6 +629,90 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
Rop4);
|
||||
}
|
||||
|
||||
DPRINT("source and dest size are NOT equal.\n");
|
||||
|
||||
DPRINT("SourceRect: (%d,%d)-(%d,%d) and DestRect: (%d,%d)-(%d,%d)\n",
|
||||
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
/* if cxSrc < 0 then we change the signs for both cxSrc and cxDest and
|
||||
* we reverse their coordinates, because these outcomes are the same.
|
||||
*/
|
||||
if (cxSrc < 0)
|
||||
{
|
||||
lTmp = SourceRect->left;
|
||||
SourceRect->left = SourceRect->right;
|
||||
SourceRect->right = lTmp;
|
||||
lTmp = DestRect->left;
|
||||
DestRect->left = DestRect->right;
|
||||
DestRect->right = lTmp;
|
||||
cxSrc = -cxSrc;
|
||||
cxDest = -cxDest;
|
||||
}
|
||||
/* if cySrc < 0 then we change the signs for both cySrc and cyDest and
|
||||
* we reverse their coordinates, because these outcomes are the same.
|
||||
*/
|
||||
if (cySrc < 0)
|
||||
{
|
||||
lTmp = DestRect->top;
|
||||
DestRect->top = DestRect->bottom;
|
||||
DestRect->bottom = lTmp;
|
||||
lTmp = SourceRect->top;
|
||||
SourceRect->top = SourceRect->bottom;
|
||||
SourceRect->bottom = lTmp;
|
||||
cySrc = -cySrc;
|
||||
cyDest = -cyDest;
|
||||
}
|
||||
|
||||
if (Case0010 || Case0111) // Horizontal Flips
|
||||
{
|
||||
DestRect->left--;
|
||||
}
|
||||
|
||||
if (Case0010 || Case0111 || Case1000 || Case1101) // Horizontal Flips
|
||||
{
|
||||
SourceRect->left--;
|
||||
SourceRect->right--;
|
||||
}
|
||||
|
||||
if (Case0001 || Case0100 || Case1011 || Case1110) // Vertical Flips
|
||||
{
|
||||
SourceRect->top--;
|
||||
SourceRect->bottom--;
|
||||
}
|
||||
|
||||
if (Case0011 || Case0110 || Case1001 || Case1100) // Horizontal and Vertical Flips
|
||||
{
|
||||
SourceRect->left--;
|
||||
SourceRect->right--;
|
||||
|
||||
SourceRect->top--;
|
||||
SourceRect->bottom--;
|
||||
}
|
||||
|
||||
if (Case0000 || Case1010) // No Flip - Just Copy
|
||||
{
|
||||
SourceRect->top++;
|
||||
SourceRect->bottom++;
|
||||
|
||||
DestRect->top++;
|
||||
DestRect->bottom++;
|
||||
}
|
||||
|
||||
if (Case0000 || Case0101) // No Flip - Just Copy
|
||||
{
|
||||
SourceRect->left++;
|
||||
SourceRect->right++;
|
||||
|
||||
DestRect->left++;
|
||||
DestRect->right++;
|
||||
|
||||
}
|
||||
|
||||
DPRINT("SourceRect: (%d,%d)-(%d,%d) and DestRect: (%d,%d)-(%d,%d)\n",
|
||||
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||
|
||||
InputClippedRect = *DestRect;
|
||||
if (InputClippedRect.right < InputClippedRect.left)
|
||||
{
|
||||
@ -429,6 +727,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
|
||||
if (NULL == psoSource)
|
||||
{
|
||||
DPRINT("Returning FALSE.\n");
|
||||
return FALSE;
|
||||
}
|
||||
InputRect = *SourceRect;
|
||||
@ -436,17 +735,28 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
if (InputRect.right < InputRect.left ||
|
||||
InputRect.bottom < InputRect.top)
|
||||
{
|
||||
DPRINT("Returning TRUE.\n");
|
||||
/* Everything clipped away, nothing to do */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DPRINT("InputRect: (%d,%d)-(%d,%d) and InputClippedRect: (%d,%d)-(%d,%d)\n",
|
||||
InputRect.left, InputRect.top, InputRect.right, InputRect.bottom,
|
||||
InputClippedRect.left, InputClippedRect.top, InputClippedRect.right, InputClippedRect.bottom);
|
||||
|
||||
if (ClipRegion->iDComplexity != DC_TRIVIAL)
|
||||
{
|
||||
if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect,
|
||||
&ClipRegion->rclBounds))
|
||||
{
|
||||
DPRINT("Returning TRUE.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DPRINT("InputClippedRect: (%d,%d)-(%d,%d) and OutputRect: (%d,%d)-(%d,%d)\n",
|
||||
InputClippedRect.left, InputClippedRect.top, InputClippedRect.right, InputClippedRect.bottom,
|
||||
OutputRect.left, OutputRect.top, OutputRect.right, OutputRect.bottom);
|
||||
|
||||
/* Update source rect */
|
||||
InputClWidth = InputClippedRect.right - InputClippedRect.left;
|
||||
InputClHeight = InputClippedRect.bottom - InputClippedRect.top;
|
||||
@ -460,9 +770,15 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Complexity = DC_TRIVIAL.\n");
|
||||
OutputRect = InputClippedRect;
|
||||
}
|
||||
|
||||
|
||||
DPRINT("InputRect: (%d,%d)-(%d,%d) and OutputRect: (%d,%d)-(%d,%d)\n",
|
||||
InputRect.left, InputRect.top, InputRect.right, InputRect.bottom,
|
||||
OutputRect.left, OutputRect.top, OutputRect.right, OutputRect.bottom);
|
||||
|
||||
if (pMaskOrigin != NULL)
|
||||
{
|
||||
MaskOrigin.x = pMaskOrigin->x;
|
||||
@ -480,6 +796,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
/* Call the driver's DrvStretchBlt if available */
|
||||
if (psurfDest->flags & HOOK_STRETCHBLTROP)
|
||||
{
|
||||
DPRINT("About to call GDIDEVFUNCS(psoDest).StretchBltROP.\n");
|
||||
/* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
|
||||
ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest,
|
||||
psoSource,
|
||||
@ -498,6 +815,25 @@ IntEngStretchBlt(SURFOBJ *psoDest,
|
||||
|
||||
if (! ret)
|
||||
{
|
||||
/* set OutputRect to follow flip */
|
||||
if (bLeftToRight)
|
||||
{
|
||||
lTmp = OutputRect.left;
|
||||
OutputRect.left = OutputRect.right;
|
||||
OutputRect.right = lTmp;
|
||||
}
|
||||
|
||||
if (bTopToBottom)
|
||||
{
|
||||
lTmp = OutputRect.top;
|
||||
OutputRect.top = OutputRect.bottom;
|
||||
OutputRect.bottom = lTmp;
|
||||
}
|
||||
|
||||
DPRINT("Calling EngStretchBltROP: InputRect: (%d,%d)-(%d,%d) and OutputRect: (%d,%d)-(%d,%d)\n",
|
||||
InputRect.left, InputRect.top, InputRect.right, InputRect.bottom,
|
||||
OutputRect.left, OutputRect.top, OutputRect.right, OutputRect.bottom);
|
||||
|
||||
ret = EngStretchBltROP(psoDest,
|
||||
psoSource,
|
||||
MaskSurf,
|
||||
|
@ -7,6 +7,8 @@
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(GdiBlt);
|
||||
|
||||
BOOL APIENTRY
|
||||
@ -480,6 +482,29 @@ NtGdiMaskBlt(
|
||||
XlateObj = &exlo.xlo;
|
||||
}
|
||||
|
||||
DPRINT("DestRect: (%d,%d)-(%d,%d) and SourcePoint is (%d,%d)\n",
|
||||
DestRect.left, DestRect.top, DestRect.right, DestRect.bottom,
|
||||
SourcePoint.x, SourcePoint.y);
|
||||
|
||||
DPRINT("nWidth is '%d' and nHeight is '%d'.\n", nWidth, nHeight);
|
||||
|
||||
/* Fix BitBlt so that it will not flip left to right */
|
||||
if ((DestRect.left > DestRect.right) && (nWidth < 0))
|
||||
{
|
||||
SourcePoint.x += nWidth;
|
||||
nWidth = -nWidth;
|
||||
}
|
||||
|
||||
/* Fix BitBlt so that it will not flip top to bottom */
|
||||
if ((DestRect.top > DestRect.bottom) && (nHeight < 0))
|
||||
{
|
||||
SourcePoint.y += nHeight;
|
||||
nHeight = -nHeight;
|
||||
}
|
||||
|
||||
/* Make Well Ordered so that we don't flip either way */
|
||||
RECTL_vMakeWellOrdered(&DestRect);
|
||||
|
||||
/* Perform the bitblt operation */
|
||||
Status = IntEngBitBlt(&BitmapDest->SurfObj,
|
||||
BitmapSrc ? &BitmapSrc->SurfObj : NULL,
|
||||
@ -563,6 +588,7 @@ GreStretchBltMask(
|
||||
BOOL UsesSource;
|
||||
BOOL UsesMask;
|
||||
ROP4 rop4;
|
||||
BOOL Case0000, Case0101, Case1010, CaseExcept;
|
||||
|
||||
rop4 = WIN32_ROP4_TO_ENG_ROP4(dwRop4);
|
||||
|
||||
@ -615,12 +641,31 @@ GreStretchBltMask(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Case0000 = ((WidthDest < 0) && (HeightDest < 0) && (WidthSrc < 0) && (HeightSrc < 0));
|
||||
Case0101 = ((WidthDest < 0) && (HeightDest > 0) && (WidthSrc < 0) && (HeightSrc > 0));
|
||||
Case1010 = ((WidthDest > 0) && (HeightDest < 0) && (WidthSrc > 0) && (HeightSrc < 0));
|
||||
CaseExcept = (Case0000 || Case0101 || Case1010);
|
||||
|
||||
pdcattr = DCDest->pdcattr;
|
||||
|
||||
DestRect.left = XOriginDest;
|
||||
DestRect.top = YOriginDest;
|
||||
DestRect.right = XOriginDest+WidthDest;
|
||||
DestRect.bottom = YOriginDest+HeightDest;
|
||||
|
||||
/* Account for possible negative span values */
|
||||
if ((WidthDest < 0) && !CaseExcept)
|
||||
{
|
||||
DestRect.left++;
|
||||
DestRect.right++;
|
||||
}
|
||||
if ((HeightDest < 0) && !CaseExcept)
|
||||
{
|
||||
DestRect.top++;
|
||||
DestRect.bottom++;
|
||||
}
|
||||
|
||||
IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);
|
||||
|
||||
DestRect.left += DCDest->ptlDCOrig.x;
|
||||
@ -638,6 +683,18 @@ GreStretchBltMask(
|
||||
SourceRect.right = XOriginSrc+WidthSrc;
|
||||
SourceRect.bottom = YOriginSrc+HeightSrc;
|
||||
|
||||
/* Account for possible negative span values */
|
||||
if ((WidthSrc < 0) && !CaseExcept)
|
||||
{
|
||||
SourceRect.left++;
|
||||
SourceRect.right++;
|
||||
}
|
||||
if ((HeightSrc < 0) && !CaseExcept)
|
||||
{
|
||||
SourceRect.top++;
|
||||
SourceRect.bottom++;
|
||||
}
|
||||
|
||||
if (UsesSource)
|
||||
{
|
||||
IntLPtoDP(DCSrc, (LPPOINT)&SourceRect, 2);
|
||||
@ -698,6 +755,10 @@ GreStretchBltMask(
|
||||
MaskPoint.y += DCMask->ptlDCOrig.y;
|
||||
}
|
||||
|
||||
DPRINT("Calling IntEngStrethBlt SourceRect: (%d,%d)-(%d,%d) and DestRect: (%d,%d)-(%d,%d).\n",
|
||||
SourceRect.left, SourceRect.top, SourceRect.right, SourceRect.bottom,
|
||||
DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
|
||||
|
||||
/* Perform the bitblt operation */
|
||||
Status = IntEngStretchBlt(&BitmapDest->SurfObj,
|
||||
BitmapSrc ? &BitmapSrc->SurfObj : NULL,
|
||||
|
@ -628,9 +628,17 @@ NtGdiSetDIBitsToDeviceInternal(
|
||||
pDestSurf = &pSurf->SurfObj;
|
||||
|
||||
/* Copy the bits */
|
||||
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
|
||||
DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n",
|
||||
rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
|
||||
ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
|
||||
|
||||
/* This fixes the large Google text on Google.com from being upside down */
|
||||
if (rcDest.top > rcDest.bottom)
|
||||
{
|
||||
RECTL_vMakeWellOrdered(&rcDest);
|
||||
ptSource.y -= SourceSize.cy;
|
||||
}
|
||||
|
||||
bResult = IntEngBitBlt(pDestSurf,
|
||||
pSourceSurf,
|
||||
pMaskSurf,
|
||||
@ -722,7 +730,7 @@ GreGetDIBitsInternal(
|
||||
&size);
|
||||
if(bitmap_type == -1)
|
||||
{
|
||||
DPRINT("Wrong bitmap format\n");
|
||||
DPRINT1("Wrong bitmap format\n");
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
ScanLines = 0;
|
||||
goto done;
|
||||
|
Loading…
Reference in New Issue
Block a user