Implement complex clipping for StretchBlt

svn path=/trunk/; revision=9388
This commit is contained in:
Gé van Geldorp 2004-05-14 22:56:18 +00:00
parent 0c9315b3dc
commit 4b8fc8e4e4
12 changed files with 516 additions and 284 deletions

View file

@ -21,7 +21,8 @@ BOOLEAN DIB_1BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode);
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode);
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PSURFGDI DestGDI, PSURFGDI SourceGDI,
RECTL* DestRect, POINTL *SourcePoint,
@ -40,7 +41,8 @@ BOOLEAN DIB_4BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode);
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode);
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PSURFGDI DestGDI, PSURFGDI SourceGDI,
RECTL* DestRect, POINTL *SourcePoint,
@ -59,7 +61,8 @@ BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode);
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode);
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PSURFGDI DestGDI, PSURFGDI SourceGDI,
RECTL* DestRect, POINTL *SourcePoint,
@ -78,7 +81,8 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode);
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode);
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PSURFGDI DestGDI, PSURFGDI SourceGDI,
RECTL* DestRect, POINTL *SourcePoint,
@ -97,7 +101,8 @@ BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode);
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode);
BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PSURFGDI DestGDI, PSURFGDI SourceGDI,
RECTL* DestRect, POINTL *SourcePoint,
@ -116,7 +121,8 @@ BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode);
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode);
BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PSURFGDI DestGDI, PSURFGDI SourceGDI,
RECTL* DestRect, POINTL *SourcePoint,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib16bpp.c,v 1.31 2004/05/10 17:07:17 weiden Exp $ */
/* $Id: dib16bpp.c,v 1.32 2004/05/14 22:56:17 gvg Exp $ */
#include <w32k.h>
VOID
@ -256,7 +256,7 @@ DIB_16BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
default:
DbgPrint("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
}
@ -468,26 +468,84 @@ void ScaleLineAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
*Target++ = *Source;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
void ScaleRectAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
static BOOLEAN
FinalCopy16(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
UINT DestY, RECTL *DestRect)
{
int NumPixels = TgtHeight;
int IntPart = ((SrcHeight / TgtHeight) * srcPitch) >> 1; //(SrcHeight / TgtHeight) * SrcWidth;
int FractPart = SrcHeight % TgtHeight;
int Mid = TgtHeight >> 1;
LONG Left, Right;
while (ClipSpans[*SpanIndex].Y < DestY
|| (ClipSpans[*SpanIndex].Y == DestY
&& ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
{
(*SpanIndex)++;
if (ClipSpansCount <= *SpanIndex)
{
/* No more spans, everything else is clipped away, we're done */
return FALSE;
}
}
while (ClipSpans[*SpanIndex].Y == DestY)
{
if (ClipSpans[*SpanIndex].X < DestRect->right)
{
Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
(Right - Left) * sizeof(PIXEL));
}
(*SpanIndex)++;
if (ClipSpansCount <= *SpanIndex)
{
/* No more spans, everything else is clipped away, we're done */
return FALSE;
}
}
return TRUE;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
BOOLEAN ScaleRectAvg16(SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
int NumPixels = DestRect->bottom - DestRect->top;
int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceGDI->SurfObj.lDelta) >> 1; /* ((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left); */
int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
int Mid = (DestRect->bottom - DestRect->top) >> 1;
int E = 0;
int skip;
PIXEL *ScanLine, *ScanLineAhead;
PIXEL *PrevSource = NULL;
PIXEL *PrevSourceAhead = NULL;
PIXEL *Target = (PIXEL *) (DestGDI->SurfObj.pvScan0 + (DestRect->top * DestGDI->SurfObj.lDelta) + 2 * DestRect->left);
PIXEL *Source = (PIXEL *) (SourceGDI->SurfObj.pvScan0 + (SourceRect->top * SourceGDI->SurfObj.lDelta) + 2 * SourceRect->left);
PSPAN ClipSpans;
UINT ClipSpansCount;
UINT SpanIndex;
LONG DestY;
skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
{
return FALSE;
}
if (0 == ClipSpansCount)
{
/* No clip spans == empty clipping region, everything clipped away */
ASSERT(NULL == ClipSpans);
return TRUE;
}
skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
NumPixels -= skip;
ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
DestY = DestRect->top;
SpanIndex = 0;
while (NumPixels-- > 0) {
if (Source != PrevSource) {
if (Source == PrevSourceAhead) {
@ -499,38 +557,57 @@ void ScaleRectAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
ScanLine = ScanLineAhead;
ScanLineAhead = tmp;
} else {
ScaleLineAvg16(ScanLine, Source, SrcWidth, TgtWidth);
ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
} /* if */
PrevSource = Source;
} /* if */
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
int x;
ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
for (x = 0; x < TgtWidth; x++)
ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
for (x = 0; x < DestRect->right - DestRect->left; x++)
ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]);
PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
} /* if */
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
Target = (PIXEL *)((BYTE *)Target + dstPitch);
if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
{
/* No more spans, everything else is clipped away, we're done */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
DestY++;
Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
Source += IntPart;
E += FractPart;
if (E >= TgtHeight) {
E -= TgtHeight;
Source = (PIXEL *)((BYTE *)Source + srcPitch);
if (E >= DestRect->bottom - DestRect->top) {
E -= DestRect->bottom - DestRect->top;
Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
} /* if */
} /* while */
if (skip > 0 && Source != PrevSource)
ScaleLineAvg16(ScanLine, Source, SrcWidth, TgtWidth);
ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
while (skip-- > 0) {
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
Target = (PIXEL *)((BYTE *)Target + dstPitch);
if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
{
/* No more spans, everything else is clipped away, we're done */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
DestY++;
Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
} /* while */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
@ -538,11 +615,10 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
BYTE *SourceLine, *DestLine;
DbgPrint("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
@ -561,12 +637,8 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
case 16:
SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 2 * SourceRect->left;
DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left;
ScaleRectAvg16((PIXEL *)DestLine, (PIXEL *)SourceLine,
SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top,
DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
return ScaleRectAvg16(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
ClipRegion, ColorTranslation, Mode);
break;
case 24:
@ -578,7 +650,7 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
default:
DbgPrint("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
DPRINT1("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib1bpp.c,v 1.27 2004/05/10 17:07:17 weiden Exp $ */
/* $Id: dib1bpp.c,v 1.28 2004/05/14 22:56:17 gvg Exp $ */
#include <w32k.h>
VOID
@ -515,7 +515,8 @@ DIB_1BPP_StretchBlt (
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib24bpp.c,v 1.26 2004/05/10 17:07:17 weiden Exp $ */
/* $Id: dib24bpp.c,v 1.27 2004/05/14 22:56:17 gvg Exp $ */
#include <w32k.h>
VOID
@ -345,7 +345,8 @@ BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib32bpp.c,v 1.26 2004/05/10 17:07:17 weiden Exp $ */
/* $Id: dib32bpp.c,v 1.27 2004/05/14 22:56:17 gvg Exp $ */
#include <w32k.h>
VOID
@ -278,7 +278,7 @@ DIB_32BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
default:
DbgPrint("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
DPRINT1("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
}
@ -437,27 +437,85 @@ void ScaleLineAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
while (skip-- > 0)
*Target++ = *Source;
}
static BOOLEAN
FinalCopy32(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
UINT DestY, RECTL *DestRect)
{
LONG Left, Right;
while (ClipSpans[*SpanIndex].Y < DestY
|| (ClipSpans[*SpanIndex].Y == DestY
&& ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
{
(*SpanIndex)++;
if (ClipSpansCount <= *SpanIndex)
{
/* No more spans, everything else is clipped away, we're done */
return FALSE;
}
}
while (ClipSpans[*SpanIndex].Y == DestY)
{
if (ClipSpans[*SpanIndex].X < DestRect->right)
{
Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
(Right - Left) * sizeof(PIXEL));
}
(*SpanIndex)++;
if (ClipSpansCount <= *SpanIndex)
{
/* No more spans, everything else is clipped away, we're done */
return FALSE;
}
}
return TRUE;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
void ScaleRectAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
BOOLEAN ScaleRectAvg32(SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
int NumPixels = TgtHeight;
int IntPart = ((SrcHeight / TgtHeight) * srcPitch) / 4; //(SrcHeight / TgtHeight) * SrcWidth;
int FractPart = SrcHeight % TgtHeight;
int Mid = TgtHeight >> 1;
int NumPixels = DestRect->bottom - DestRect->top;
int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceGDI->SurfObj.lDelta) / 4; //((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left);
int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
int Mid = (DestRect->bottom - DestRect->top) >> 1;
int E = 0;
int skip;
PIXEL *ScanLine, *ScanLineAhead;
PIXEL *PrevSource = NULL;
PIXEL *PrevSourceAhead = NULL;
PIXEL *Target = (PIXEL *) (DestGDI->SurfObj.pvScan0 + (DestRect->top * DestGDI->SurfObj.lDelta) + 4 * DestRect->left);
PIXEL *Source = (PIXEL *) (SourceGDI->SurfObj.pvScan0 + (SourceRect->top * SourceGDI->SurfObj.lDelta) + 4 * SourceRect->left);
PSPAN ClipSpans;
UINT ClipSpansCount;
UINT SpanIndex;
LONG DestY;
skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
{
return FALSE;
}
if (0 == ClipSpansCount)
{
/* No clip spans == empty clipping region, everything clipped away */
ASSERT(NULL == ClipSpans);
return TRUE;
}
skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
NumPixels -= skip;
ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
DestY = DestRect->top;
SpanIndex = 0;
while (NumPixels-- > 0) {
if (Source != PrevSource) {
if (Source == PrevSourceAhead) {
@ -469,38 +527,57 @@ void ScaleRectAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
ScanLine = ScanLineAhead;
ScanLineAhead = tmp;
} else {
ScaleLineAvg32(ScanLine, Source, SrcWidth, TgtWidth);
ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
} /* if */
PrevSource = Source;
} /* if */
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
int x;
ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
for (x = 0; x < TgtWidth; x++)
ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
for (x = 0; x < DestRect->right - DestRect->left; x++)
ScanLine[x] = average32(ScanLine[x], ScanLineAhead[x]);
PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
} /* if */
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
Target = (PIXEL *)((BYTE *)Target + dstPitch);
if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
{
/* No more spans, everything else is clipped away, we're done */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
DestY++;
Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
Source += IntPart;
E += FractPart;
if (E >= TgtHeight) {
E -= TgtHeight;
Source = (PIXEL *)((BYTE *)Source + srcPitch);
if (E >= DestRect->bottom - DestRect->top) {
E -= DestRect->bottom - DestRect->top;
Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
} /* if */
} /* while */
if (skip > 0 && Source != PrevSource)
ScaleLineAvg32(ScanLine, Source, SrcWidth, TgtWidth);
ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
while (skip-- > 0) {
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
Target = (PIXEL *)((BYTE *)Target + dstPitch);
if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
{
/* No more spans, everything else is clipped away, we're done */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
DestY++;
Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
} /* while */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
@ -508,11 +585,10 @@ BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
BYTE *SourceLine, *DestLine;
DbgPrint("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
DPRINT("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
@ -539,15 +615,12 @@ BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
case 32:
SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 4 * SourceRect->left;
DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left;
ScaleRectAvg32((PIXEL *)DestLine, (PIXEL *)SourceLine,
SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top,
DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
return ScaleRectAvg32(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
ClipRegion, ColorTranslation, Mode);
break;
default:
//DbgPrint("DIB_32BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
//DPRINT1("DIB_32BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib4bpp.c,v 1.34 2004/05/10 17:07:17 weiden Exp $ */
/* $Id: dib4bpp.c,v 1.35 2004/05/14 22:56:17 gvg Exp $ */
#include <w32k.h>
VOID
@ -390,7 +390,8 @@ BOOLEAN DIB_4BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
DbgPrint("DIB_4BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib8bpp.c,v 1.25 2004/05/10 17:07:17 weiden Exp $ */
/* $Id: dib8bpp.c,v 1.26 2004/05/14 22:56:17 gvg Exp $ */
#include <w32k.h>
VOID
@ -252,7 +252,7 @@ DIB_8BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
default:
DbgPrint("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
DPRINT1("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
}
@ -432,26 +432,84 @@ void ScaleLineAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
*Target++ = *Source;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
static BOOLEAN
FinalCopy8(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
UINT DestY, RECTL *DestRect)
{
int NumPixels = TgtHeight;
int IntPart = ((SrcHeight / TgtHeight) * srcPitch); //(SrcHeight / TgtHeight) * SrcWidth;
int FractPart = SrcHeight % TgtHeight;
int Mid = TgtHeight >> 1;
LONG Left, Right;
while (ClipSpans[*SpanIndex].Y < DestY
|| (ClipSpans[*SpanIndex].Y == DestY
&& ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
{
(*SpanIndex)++;
if (ClipSpansCount <= *SpanIndex)
{
/* No more spans, everything else is clipped away, we're done */
return FALSE;
}
}
while (ClipSpans[*SpanIndex].Y == DestY)
{
if (ClipSpans[*SpanIndex].X < DestRect->right)
{
Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
(Right - Left) * sizeof(PIXEL));
}
(*SpanIndex)++;
if (ClipSpansCount <= *SpanIndex)
{
/* No more spans, everything else is clipped away, we're done */
return FALSE;
}
}
return TRUE;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
BOOLEAN ScaleRectAvg8(SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
int NumPixels = DestRect->bottom - DestRect->top;
int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceGDI->SurfObj.lDelta); //((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left);
int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
int Mid = (DestRect->bottom - DestRect->top) >> 1;
int E = 0;
int skip;
PIXEL *ScanLine, *ScanLineAhead;
PIXEL *PrevSource = NULL;
PIXEL *PrevSourceAhead = NULL;
PIXEL *Target = (PIXEL *) (DestGDI->SurfObj.pvScan0 + (DestRect->top * DestGDI->SurfObj.lDelta) + DestRect->left);
PIXEL *Source = (PIXEL *) (SourceGDI->SurfObj.pvScan0 + (SourceRect->top * SourceGDI->SurfObj.lDelta) + SourceRect->left);
PSPAN ClipSpans;
UINT ClipSpansCount;
UINT SpanIndex;
LONG DestY;
skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
{
return FALSE;
}
if (0 == ClipSpansCount)
{
/* No clip spans == empty clipping region, everything clipped away */
ASSERT(NULL == ClipSpans);
return TRUE;
}
skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
NumPixels -= skip;
ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
DestY = DestRect->top;
SpanIndex = 0;
while (NumPixels-- > 0) {
if (Source != PrevSource) {
if (Source == PrevSourceAhead) {
@ -463,49 +521,67 @@ void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
ScanLine = ScanLineAhead;
ScanLineAhead = tmp;
} else {
ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
} /* if */
PrevSource = Source;
} /* if */
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
int x;
ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
for (x = 0; x < TgtWidth; x++)
ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
for (x = 0; x < DestRect->right - DestRect->left; x++)
ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
} /* if */
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
Target = (PIXEL *)((BYTE *)Target + dstPitch);
if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
{
/* No more spans, everything else is clipped away, we're done */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
DestY++;
Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
Source += IntPart;
E += FractPart;
if (E >= TgtHeight) {
E -= TgtHeight;
Source = (PIXEL *)((BYTE *)Source + srcPitch);
if (E >= DestRect->bottom - DestRect->top) {
E -= DestRect->bottom - DestRect->top;
Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
} /* if */
} /* while */
if (skip > 0 && Source != PrevSource)
ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
while (skip-- > 0) {
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
Target = (PIXEL *)((BYTE *)Target + dstPitch);
if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
{
/* No more spans, everything else is clipped away, we're done */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
DestY++;
Target = (PIXEL *)((BYTE *)Target + DestGDI->SurfObj.lDelta);
} /* while */
ExFreePool(ClipSpans);
ExFreePool(ScanLine);
ExFreePool(ScanLineAhead);
return TRUE;
}
BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
BYTE *SourceLine, *DestLine;
DbgPrint("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
DPRINT("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
@ -520,12 +596,8 @@ BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
case 8:
SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left;
DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left;
ScaleRectAvg8((PIXEL *)DestLine, (PIXEL *)SourceLine,
SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top,
DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
return ScaleRectAvg8(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
ClipRegion, ColorTranslation, Mode);
break;
case 16:
@ -541,7 +613,7 @@ BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
break;
default:
DbgPrint("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
DPRINT1("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bitblt.c,v 1.54 2004/05/10 17:07:17 weiden Exp $
/* $Id: bitblt.c,v 1.55 2004/05/14 22:56:18 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -45,6 +45,7 @@ typedef BOOLEAN STDCALL (*PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
SURFOBJ* InputObj,
SURFGDI* InputGDI,
SURFOBJ* Mask,
CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
RECTL* InputRect,
@ -593,6 +594,7 @@ CallDibStretchBlt(SURFOBJ* OutputObj,
SURFOBJ* InputObj,
SURFGDI* InputGDI,
SURFOBJ* Mask,
CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation,
RECTL* OutputRect,
RECTL* InputRect,
@ -609,7 +611,7 @@ CallDibStretchBlt(SURFOBJ* OutputObj,
{
RealBrushOrigin = *BrushOrigin;
}
return OutputGDI->DIB_StretchBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ColorTranslation, Mode);
return OutputGDI->DIB_StretchBlt(OutputObj, InputObj, OutputGDI, InputGDI, OutputRect, InputRect, MaskOrigin, RealBrushOrigin, ClipRegion, ColorTranslation, Mode);
}
@ -631,10 +633,6 @@ EngStretchBlt(
{
// www.osr.com/ddk/graphics/gdifncs_0bs7.htm
BYTE clippingType;
RECTL CombinedRect;
// RECT_ENUM RectEnum;
// BOOL EnumMore;
SURFGDI* OutputGDI;
SURFGDI* InputGDI;
POINTL InputPoint;
@ -645,30 +643,26 @@ EngStretchBlt(
INTENG_ENTER_LEAVE EnterLeaveDest;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
PSTRETCHRECTFUNC BltRectFunc;
PSTRETCHRECTFUNC BltRectFunc;
BOOLEAN Ret;
RECTL ClipRect;
// unsigned i;
POINTL Pt;
// ULONG Direction;
POINTL AdjustedBrushOrigin;
POINTL AdjustedBrushOrigin;
InputRect.left = prclSrc->left;
InputRect.right = prclSrc->right;
InputRect.top = prclSrc->top;
InputRect.bottom = prclSrc->bottom;
InputRect.left = prclSrc->left;
InputRect.right = prclSrc->right;
InputRect.top = prclSrc->top;
InputRect.bottom = prclSrc->bottom;
if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
{
return FALSE;
return FALSE;
}
InputPoint.x = InputRect.left + Translate.x;
InputPoint.y = InputRect.top + Translate.y;
InputPoint.x = InputRect.left + Translate.x;
InputPoint.y = InputRect.top + Translate.y;
if (NULL != InputObj)
{
InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
}
else
{
@ -676,44 +670,19 @@ EngStretchBlt(
}
OutputRect = *prclDest;
if (NULL != ClipRegion)
{
if (OutputRect.left < ClipRegion->rclBounds.left)
{
InputRect.left += ClipRegion->rclBounds.left - OutputRect.left;
InputPoint.x += ClipRegion->rclBounds.left - OutputRect.left;
OutputRect.left = ClipRegion->rclBounds.left;
}
if (ClipRegion->rclBounds.right < OutputRect.right)
{
InputRect.right -= OutputRect.right - ClipRegion->rclBounds.right;
OutputRect.right = ClipRegion->rclBounds.right;
}
if (OutputRect.top < ClipRegion->rclBounds.top)
{
InputRect.top += ClipRegion->rclBounds.top - OutputRect.top;
InputPoint.y += ClipRegion->rclBounds.top - OutputRect.top;
OutputRect.top = ClipRegion->rclBounds.top;
}
if (ClipRegion->rclBounds.bottom < OutputRect.bottom)
{
InputRect.bottom -= OutputRect.bottom - ClipRegion->rclBounds.bottom;
OutputRect.bottom = ClipRegion->rclBounds.bottom;
}
}
/* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
nothing to do */
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
{
IntEngLeave(&EnterLeaveSource);
return TRUE;
IntEngLeave(&EnterLeaveSource);
return TRUE;
}
if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
{
IntEngLeave(&EnterLeaveSource);
return FALSE;
IntEngLeave(&EnterLeaveSource);
return FALSE;
}
OutputRect.left = prclDest->left + Translate.x;
@ -721,28 +690,22 @@ EngStretchBlt(
OutputRect.top = prclDest->top + Translate.y;
OutputRect.bottom = prclDest->bottom + Translate.y;
if(BrushOrigin)
{
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
}
if (NULL != BrushOrigin)
{
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
}
else
AdjustedBrushOrigin = Translate;
{
AdjustedBrushOrigin = Translate;
}
if (NULL != OutputObj)
{
OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
}
// Determine clipping type
if (ClipRegion == (CLIPOBJ *) NULL)
{
clippingType = DC_TRIVIAL;
} else {
clippingType = ClipRegion->iDComplexity;
}
if (Mask != NULL)//(0xaacc == Rop4)
if (Mask != NULL)
{
//BltRectFunc = BltMask;
DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
@ -757,70 +720,9 @@ EngStretchBlt(
}
switch(clippingType)
{
case DC_TRIVIAL:
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
&OutputRect, &InputRect, MaskOrigin, &AdjustedBrushOrigin, Mode);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
&OutputRect, &InputRect, MaskOrigin, &AdjustedBrushOrigin, Mode);
//Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
// &CombinedRect, &Pt, MaskOrigin, Brush, BrushOrigin, Rop4);
DPRINT("EngStretchBlt() doesn't support DC_RECT clipping yet, so blitting w/o clip.\n");
break;
// TODO: Complex clipping
/*
case DC_COMPLEX:
Ret = TRUE;
if (OutputObj == InputObj)
{
if (OutputRect.top < InputPoint.y)
{
Direction = OutputRect.left < InputPoint.x ? CD_RIGHTDOWN : CD_LEFTDOWN;
}
else
{
Direction = OutputRect.left < InputPoint.x ? CD_RIGHTUP : CD_LEFTUP;
}
}
else
{
Direction = CD_ANY;
}
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
do
{
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
ClipRect.left = RectEnum.arcl[i].left + Translate.x;
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect);
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ColorTranslation,
&CombinedRect, &Pt, MaskOrigin, Brush, &AdjustedBrushOrigin, Rop4) &&
Ret;
}
}
while(EnumMore);
break;
*/
}
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ClipRegion,
ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
&AdjustedBrushOrigin, Mode);
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
@ -844,8 +746,6 @@ IntEngStretchBlt(SURFOBJ *DestObj,
BOOLEAN ret;
SURFGDI *DestGDI;
SURFGDI *SourceGDI;
RECTL OutputRect;
RECTL InputRect;
COLORADJUSTMENT ca;
POINT MaskOrigin;
@ -854,43 +754,19 @@ IntEngStretchBlt(SURFOBJ *DestObj,
MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
}
if (NULL != SourceRect)
{
InputRect = *SourceRect;
}
// FIXME: Clipping is taken from IntEngBitBlt w/o modifications!
/* Clip against the bounds of the clipping region so we won't try to write
* outside the surface */
if (NULL != ClipRegion)
{
if (! EngIntersectRect(&OutputRect, DestRect, &ClipRegion->rclBounds))
{
return TRUE;
}
DPRINT("Clipping isn't handled in IntEngStretchBlt() correctly yet\n");
//InputPoint.x += OutputRect.left - DestRect->left;
//InputPoint.y += OutputRect.top - DestRect->top;
}
else
{
OutputRect = *DestRect;
}
if (NULL != SourceObj)
{
SourceGDI = (SURFGDI*) AccessInternalObjectFromUserObject(SourceObj);
MouseSafetyOnDrawStart(SourceObj, SourceGDI, InputRect.left, InputRect.top,
(InputRect.left + abs(InputRect.right - InputRect.left)),
(InputRect.top + abs(InputRect.bottom - InputRect.top)));
MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourceRect->left, SourceRect->top,
(SourceRect->left + abs(SourceRect->right - SourceRect->left)),
(SourceRect->top + abs(SourceRect->bottom - SourceRect->top)));
}
/* No success yet */
ret = FALSE;
DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
OutputRect.right, OutputRect.bottom);
MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top,
DestRect->right, DestRect->bottom);
/* Prepare color adjustment */
@ -902,7 +778,7 @@ IntEngStretchBlt(SURFOBJ *DestObj,
// FIXME: MaskOrigin is always NULL !
IntLockGDIDriver(DestGDI);
ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
&ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
IntUnLockGDIDriver(DestGDI);
}
@ -910,7 +786,7 @@ IntEngStretchBlt(SURFOBJ *DestObj,
{
// FIXME: see previous fixme
ret = EngStretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
&ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
}
MouseSafetyOnDrawEnd(DestObj, DestGDI);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: clip.c,v 1.20 2004/05/10 17:07:17 weiden Exp $
/* $Id: clip.c,v 1.21 2004/05/14 22:56:18 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -333,4 +333,123 @@ CLIPOBJ_bEnum(IN CLIPOBJ* ClipObj,
return ClipGDI->EnumPos < ClipGDI->EnumRects.c;
}
static int
CompareSpans(const PSPAN Span1, const PSPAN Span2)
{
int Cmp;
if (Span1->Y < Span2->Y)
{
Cmp = -1;
}
else if (Span2->Y < Span1->Y)
{
Cmp = +1;
}
else
{
if (Span1->X < Span2->X)
{
Cmp = -1;
}
else if (Span2->X < Span1->X)
{
Cmp = +1;
}
else
{
Cmp = 0;
}
}
return Cmp;
}
BOOLEAN FASTCALL
ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary)
{
BOOL EnumMore;
UINT i, NewCount;
RECT_ENUM RectEnum;
PSPAN NewSpans;
RECTL *Rect;
ASSERT(Boundary->top <= Boundary->bottom && Boundary->left <= Boundary->right);
*Spans = NULL;
if (NULL == ClipRegion || DC_TRIVIAL == ClipRegion->iDComplexity)
{
*Count = Boundary->bottom - Boundary->top;
if (0 != *Count)
{
*Spans = ExAllocatePoolWithTag(PagedPool, *Count * sizeof(SPAN), TAG_CLIP);
if (NULL == *Spans)
{
*Count = 0;
return FALSE;
}
for (i = 0; i < Boundary->bottom - Boundary->top; i++)
{
(*Spans)[i].X = Boundary->left;
(*Spans)[i].Y = Boundary->top + i;
(*Spans)[i].Width = Boundary->right - Boundary->left;
}
}
return TRUE;
}
*Count = 0;
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
do
{
EnumMore = CLIPOBJ_bEnum(ClipRegion, (ULONG) sizeof(RECT_ENUM), (PVOID) &RectEnum);
NewCount = *Count;
for (i = 0; i < RectEnum.c; i++)
{
NewCount += RectEnum.arcl[i].bottom - RectEnum.arcl[i].top;
}
if (NewCount != *Count)
{
NewSpans = ExAllocatePoolWithTag(PagedPool, NewCount * sizeof(SPAN), TAG_CLIP);
if (NULL == NewSpans)
{
if (NULL != *Spans)
{
ExFreePool(*Spans);
*Spans = NULL;
}
*Count = 0;
return FALSE;
}
if (0 != *Count)
{
RtlCopyMemory(NewSpans, *Spans, *Count * sizeof(SPAN));
ExFreePool(*Spans);
}
*Spans = NewSpans;
}
for (Rect = RectEnum.arcl; Rect < RectEnum.arcl + RectEnum.c; Rect++)
{
for (i = 0; i < Rect->bottom - Rect->top; i++)
{
(*Spans)[*Count].X = Rect->left;
(*Spans)[*Count].Y = Rect->top + i;
(*Spans)[*Count].Width = Rect->right - Rect->left;
(*Count)++;
}
}
ASSERT(*Count == NewCount);
}
while (EnumMore);
if (0 != *Count)
{
EngSort((PBYTE) *Spans, sizeof(SPAN), *Count, (SORTCOMP) CompareSpans);
}
return TRUE;
}
/* EOF */

View file

@ -32,4 +32,13 @@ typedef struct _RECT_ENUM
RECTL arcl[ENUM_RECT_LIMIT];
} RECT_ENUM;
typedef struct tagSPAN
{
LONG Y;
LONG X;
ULONG Width;
} SPAN, *PSPAN;
BOOLEAN FASTCALL ClipobjToSpans(PSPAN *Spans, UINT *Count, CLIPOBJ *ClipRegion, PRECTL Boundary);
#endif

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: surface.c,v 1.38 2004/05/10 17:07:17 weiden Exp $
/* $Id: surface.c,v 1.39 2004/05/14 22:56:18 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -110,7 +110,8 @@ static BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrign,
XLATEOBJ *ColorTranslation, ULONG Mode)
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
return FALSE;
}

View file

@ -26,6 +26,7 @@
#define TAG_BEZIER TAG('B', 'E', 'Z', 'R') /* bezier */
#define TAG_BITMAP TAG('B', 'T', 'M', 'P') /* bitmap */
#define TAG_PATBLT TAG('P', 'B', 'L', 'T') /* patblt */
#define TAG_CLIP TAG('C', 'L', 'I', 'P') /* clipping */
#define TAG_COORD TAG('C', 'O', 'R', 'D') /* coords */
#define TAG_DC TAG('D', 'C', 'D', 'C') /* dc */
#define TAG_GDIOBJ TAG('G', 'D', 'I', 'O') /* gdi obj */