mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:35:47 +00:00
Implement complex clipping for StretchBlt
svn path=/trunk/; revision=9388
This commit is contained in:
parent
0c9315b3dc
commit
4b8fc8e4e4
12 changed files with 516 additions and 284 deletions
|
@ -21,7 +21,8 @@ BOOLEAN DIB_1BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode);
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode);
|
||||||
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
||||||
RECTL* DestRect, POINTL *SourcePoint,
|
RECTL* DestRect, POINTL *SourcePoint,
|
||||||
|
@ -40,7 +41,8 @@ BOOLEAN DIB_4BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode);
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode);
|
||||||
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
||||||
RECTL* DestRect, POINTL *SourcePoint,
|
RECTL* DestRect, POINTL *SourcePoint,
|
||||||
|
@ -59,7 +61,8 @@ BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode);
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode);
|
||||||
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
||||||
RECTL* DestRect, POINTL *SourcePoint,
|
RECTL* DestRect, POINTL *SourcePoint,
|
||||||
|
@ -78,7 +81,8 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode);
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode);
|
||||||
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
||||||
RECTL* DestRect, POINTL *SourcePoint,
|
RECTL* DestRect, POINTL *SourcePoint,
|
||||||
|
@ -97,7 +101,8 @@ BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode);
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode);
|
||||||
BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
||||||
RECTL* DestRect, POINTL *SourcePoint,
|
RECTL* DestRect, POINTL *SourcePoint,
|
||||||
|
@ -116,7 +121,8 @@ BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode);
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode);
|
||||||
BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
PSURFGDI DestGDI, PSURFGDI SourceGDI,
|
||||||
RECTL* DestRect, POINTL *SourcePoint,
|
RECTL* DestRect, POINTL *SourcePoint,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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>
|
#include <w32k.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -256,7 +256,7 @@ DIB_16BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,26 +468,84 @@ void ScaleLineAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
|
||||||
*Target++ = *Source;
|
*Target++ = *Source;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
|
static BOOLEAN
|
||||||
void ScaleRectAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
|
FinalCopy16(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
|
||||||
int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
|
UINT DestY, RECTL *DestRect)
|
||||||
{
|
{
|
||||||
int NumPixels = TgtHeight;
|
LONG Left, Right;
|
||||||
int IntPart = ((SrcHeight / TgtHeight) * srcPitch) >> 1; //(SrcHeight / TgtHeight) * SrcWidth;
|
|
||||||
int FractPart = SrcHeight % TgtHeight;
|
while (ClipSpans[*SpanIndex].Y < DestY
|
||||||
int Mid = TgtHeight >> 1;
|
|| (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 E = 0;
|
||||||
int skip;
|
int skip;
|
||||||
PIXEL *ScanLine, *ScanLineAhead;
|
PIXEL *ScanLine, *ScanLineAhead;
|
||||||
PIXEL *PrevSource = NULL;
|
PIXEL *PrevSource = NULL;
|
||||||
PIXEL *PrevSourceAhead = 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;
|
NumPixels -= skip;
|
||||||
|
|
||||||
ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
|
ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
|
||||||
ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
|
ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
|
||||||
|
|
||||||
|
DestY = DestRect->top;
|
||||||
|
SpanIndex = 0;
|
||||||
while (NumPixels-- > 0) {
|
while (NumPixels-- > 0) {
|
||||||
if (Source != PrevSource) {
|
if (Source != PrevSource) {
|
||||||
if (Source == PrevSourceAhead) {
|
if (Source == PrevSourceAhead) {
|
||||||
|
@ -499,38 +557,57 @@ void ScaleRectAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
|
||||||
ScanLine = ScanLineAhead;
|
ScanLine = ScanLineAhead;
|
||||||
ScanLineAhead = tmp;
|
ScanLineAhead = tmp;
|
||||||
} else {
|
} else {
|
||||||
ScaleLineAvg16(ScanLine, Source, SrcWidth, TgtWidth);
|
ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
} /* if */
|
} /* if */
|
||||||
PrevSource = Source;
|
PrevSource = Source;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
|
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
|
||||||
int x;
|
int x;
|
||||||
ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
|
ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
for (x = 0; x < TgtWidth; x++)
|
for (x = 0; x < DestRect->right - DestRect->left; x++)
|
||||||
ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]);
|
ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]);
|
||||||
PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
|
PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
|
if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
|
||||||
Target = (PIXEL *)((BYTE *)Target + dstPitch);
|
{
|
||||||
|
/* 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;
|
Source += IntPart;
|
||||||
E += FractPart;
|
E += FractPart;
|
||||||
if (E >= TgtHeight) {
|
if (E >= DestRect->bottom - DestRect->top) {
|
||||||
E -= TgtHeight;
|
E -= DestRect->bottom - DestRect->top;
|
||||||
Source = (PIXEL *)((BYTE *)Source + srcPitch);
|
Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
if (skip > 0 && Source != PrevSource)
|
if (skip > 0 && Source != PrevSource)
|
||||||
ScaleLineAvg16(ScanLine, Source, SrcWidth, TgtWidth);
|
ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
while (skip-- > 0) {
|
while (skip-- > 0) {
|
||||||
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
|
if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
|
||||||
Target = (PIXEL *)((BYTE *)Target + dstPitch);
|
{
|
||||||
|
/* 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 */
|
} /* while */
|
||||||
|
|
||||||
|
ExFreePool(ClipSpans);
|
||||||
ExFreePool(ScanLine);
|
ExFreePool(ScanLine);
|
||||||
ExFreePool(ScanLineAhead);
|
ExFreePool(ScanLineAhead);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
|
//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,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
BYTE *SourceLine, *DestLine;
|
DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||||
|
|
||||||
DbgPrint("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,
|
SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||||
|
|
||||||
|
@ -561,12 +637,8 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 2 * SourceRect->left;
|
return ScaleRectAvg16(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
|
||||||
DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left;
|
ClipRegion, ColorTranslation, Mode);
|
||||||
|
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
|
@ -578,7 +650,7 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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>
|
#include <w32k.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -515,7 +515,8 @@ DIB_1BPP_StretchBlt (
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
DbgPrint("DIB_1BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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>
|
#include <w32k.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -345,7 +345,8 @@ BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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>
|
#include <w32k.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -278,7 +278,7 @@ DIB_32BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,26 +438,84 @@ void ScaleLineAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
|
||||||
*Target++ = *Source;
|
*Target++ = *Source;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
|
static BOOLEAN
|
||||||
void ScaleRectAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
|
FinalCopy32(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
|
||||||
int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
|
UINT DestY, RECTL *DestRect)
|
||||||
{
|
{
|
||||||
int NumPixels = TgtHeight;
|
LONG Left, Right;
|
||||||
int IntPart = ((SrcHeight / TgtHeight) * srcPitch) / 4; //(SrcHeight / TgtHeight) * SrcWidth;
|
|
||||||
int FractPart = SrcHeight % TgtHeight;
|
while (ClipSpans[*SpanIndex].Y < DestY
|
||||||
int Mid = TgtHeight >> 1;
|
|| (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 ScaleRectAvg32(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) / 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 E = 0;
|
||||||
int skip;
|
int skip;
|
||||||
PIXEL *ScanLine, *ScanLineAhead;
|
PIXEL *ScanLine, *ScanLineAhead;
|
||||||
PIXEL *PrevSource = NULL;
|
PIXEL *PrevSource = NULL;
|
||||||
PIXEL *PrevSourceAhead = 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;
|
NumPixels -= skip;
|
||||||
|
|
||||||
ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
|
ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
|
||||||
ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
|
ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
|
||||||
|
|
||||||
|
DestY = DestRect->top;
|
||||||
|
SpanIndex = 0;
|
||||||
while (NumPixels-- > 0) {
|
while (NumPixels-- > 0) {
|
||||||
if (Source != PrevSource) {
|
if (Source != PrevSource) {
|
||||||
if (Source == PrevSourceAhead) {
|
if (Source == PrevSourceAhead) {
|
||||||
|
@ -469,38 +527,57 @@ void ScaleRectAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
|
||||||
ScanLine = ScanLineAhead;
|
ScanLine = ScanLineAhead;
|
||||||
ScanLineAhead = tmp;
|
ScanLineAhead = tmp;
|
||||||
} else {
|
} else {
|
||||||
ScaleLineAvg32(ScanLine, Source, SrcWidth, TgtWidth);
|
ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
} /* if */
|
} /* if */
|
||||||
PrevSource = Source;
|
PrevSource = Source;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
|
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
|
||||||
int x;
|
int x;
|
||||||
ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
|
ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
for (x = 0; x < TgtWidth; x++)
|
for (x = 0; x < DestRect->right - DestRect->left; x++)
|
||||||
ScanLine[x] = average32(ScanLine[x], ScanLineAhead[x]);
|
ScanLine[x] = average32(ScanLine[x], ScanLineAhead[x]);
|
||||||
PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
|
PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
|
if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
|
||||||
Target = (PIXEL *)((BYTE *)Target + dstPitch);
|
{
|
||||||
|
/* 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;
|
Source += IntPart;
|
||||||
E += FractPart;
|
E += FractPart;
|
||||||
if (E >= TgtHeight) {
|
if (E >= DestRect->bottom - DestRect->top) {
|
||||||
E -= TgtHeight;
|
E -= DestRect->bottom - DestRect->top;
|
||||||
Source = (PIXEL *)((BYTE *)Source + srcPitch);
|
Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
if (skip > 0 && Source != PrevSource)
|
if (skip > 0 && Source != PrevSource)
|
||||||
ScaleLineAvg32(ScanLine, Source, SrcWidth, TgtWidth);
|
ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
while (skip-- > 0) {
|
while (skip-- > 0) {
|
||||||
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
|
if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
|
||||||
Target = (PIXEL *)((BYTE *)Target + dstPitch);
|
{
|
||||||
|
/* 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 */
|
} /* while */
|
||||||
|
|
||||||
|
ExFreePool(ClipSpans);
|
||||||
ExFreePool(ScanLine);
|
ExFreePool(ScanLine);
|
||||||
ExFreePool(ScanLineAhead);
|
ExFreePool(ScanLineAhead);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
|
//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,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
BYTE *SourceLine, *DestLine;
|
DPRINT("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||||
|
|
||||||
DbgPrint("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,
|
SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||||
|
|
||||||
|
@ -539,15 +615,12 @@ BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 4 * SourceRect->left;
|
return ScaleRectAvg32(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
|
||||||
DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left;
|
ClipRegion, ColorTranslation, Mode);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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>
|
#include <w32k.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -390,7 +390,8 @@ BOOLEAN DIB_4BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
DbgPrint("DIB_4BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
DbgPrint("DIB_4BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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>
|
#include <w32k.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -252,7 +252,7 @@ DIB_8BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,26 +432,84 @@ void ScaleLineAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
|
||||||
*Target++ = *Source;
|
*Target++ = *Source;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
|
static BOOLEAN
|
||||||
void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
|
FinalCopy8(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
|
||||||
int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
|
UINT DestY, RECTL *DestRect)
|
||||||
{
|
{
|
||||||
int NumPixels = TgtHeight;
|
LONG Left, Right;
|
||||||
int IntPart = ((SrcHeight / TgtHeight) * srcPitch); //(SrcHeight / TgtHeight) * SrcWidth;
|
|
||||||
int FractPart = SrcHeight % TgtHeight;
|
while (ClipSpans[*SpanIndex].Y < DestY
|
||||||
int Mid = TgtHeight >> 1;
|
|| (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 E = 0;
|
||||||
int skip;
|
int skip;
|
||||||
PIXEL *ScanLine, *ScanLineAhead;
|
PIXEL *ScanLine, *ScanLineAhead;
|
||||||
PIXEL *PrevSource = NULL;
|
PIXEL *PrevSource = NULL;
|
||||||
PIXEL *PrevSourceAhead = 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;
|
NumPixels -= skip;
|
||||||
|
|
||||||
ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
|
ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
|
||||||
ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
|
ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
|
||||||
|
|
||||||
|
DestY = DestRect->top;
|
||||||
|
SpanIndex = 0;
|
||||||
while (NumPixels-- > 0) {
|
while (NumPixels-- > 0) {
|
||||||
if (Source != PrevSource) {
|
if (Source != PrevSource) {
|
||||||
if (Source == PrevSourceAhead) {
|
if (Source == PrevSourceAhead) {
|
||||||
|
@ -463,49 +521,67 @@ void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
|
||||||
ScanLine = ScanLineAhead;
|
ScanLine = ScanLineAhead;
|
||||||
ScanLineAhead = tmp;
|
ScanLineAhead = tmp;
|
||||||
} else {
|
} else {
|
||||||
ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
|
ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
} /* if */
|
} /* if */
|
||||||
PrevSource = Source;
|
PrevSource = Source;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
|
if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta)) {
|
||||||
int x;
|
int x;
|
||||||
ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
|
ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
for (x = 0; x < TgtWidth; x++)
|
for (x = 0; x < DestRect->right - DestRect->left; x++)
|
||||||
ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
|
ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
|
||||||
PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
|
PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
|
if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
|
||||||
Target = (PIXEL *)((BYTE *)Target + dstPitch);
|
{
|
||||||
|
/* 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;
|
Source += IntPart;
|
||||||
E += FractPart;
|
E += FractPart;
|
||||||
if (E >= TgtHeight) {
|
if (E >= DestRect->bottom - DestRect->top) {
|
||||||
E -= TgtHeight;
|
E -= DestRect->bottom - DestRect->top;
|
||||||
Source = (PIXEL *)((BYTE *)Source + srcPitch);
|
Source = (PIXEL *)((BYTE *)Source + SourceGDI->SurfObj.lDelta);
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
if (skip > 0 && Source != PrevSource)
|
if (skip > 0 && Source != PrevSource)
|
||||||
ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
|
ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
|
||||||
while (skip-- > 0) {
|
while (skip-- > 0) {
|
||||||
memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
|
if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
|
||||||
Target = (PIXEL *)((BYTE *)Target + dstPitch);
|
{
|
||||||
|
/* 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 */
|
} /* while */
|
||||||
|
|
||||||
|
ExFreePool(ClipSpans);
|
||||||
ExFreePool(ScanLine);
|
ExFreePool(ScanLine);
|
||||||
ExFreePool(ScanLineAhead);
|
ExFreePool(ScanLineAhead);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrigin,
|
POINTL* MaskOrigin, POINTL BrushOrigin,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
BYTE *SourceLine, *DestLine;
|
DPRINT("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||||
|
|
||||||
DbgPrint("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,
|
SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||||
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
||||||
|
|
||||||
|
@ -520,12 +596,8 @@ BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left;
|
return ScaleRectAvg8(DestGDI, SourceGDI, DestRect, SourceRect, MaskOrigin, BrushOrigin,
|
||||||
DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left;
|
ClipRegion, ColorTranslation, Mode);
|
||||||
|
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
|
@ -541,7 +613,7 @@ BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -45,6 +45,7 @@ typedef BOOLEAN STDCALL (*PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
|
||||||
SURFOBJ* InputObj,
|
SURFOBJ* InputObj,
|
||||||
SURFGDI* InputGDI,
|
SURFGDI* InputGDI,
|
||||||
SURFOBJ* Mask,
|
SURFOBJ* Mask,
|
||||||
|
CLIPOBJ* ClipRegion,
|
||||||
XLATEOBJ* ColorTranslation,
|
XLATEOBJ* ColorTranslation,
|
||||||
RECTL* OutputRect,
|
RECTL* OutputRect,
|
||||||
RECTL* InputRect,
|
RECTL* InputRect,
|
||||||
|
@ -593,6 +594,7 @@ CallDibStretchBlt(SURFOBJ* OutputObj,
|
||||||
SURFOBJ* InputObj,
|
SURFOBJ* InputObj,
|
||||||
SURFGDI* InputGDI,
|
SURFGDI* InputGDI,
|
||||||
SURFOBJ* Mask,
|
SURFOBJ* Mask,
|
||||||
|
CLIPOBJ* ClipRegion,
|
||||||
XLATEOBJ* ColorTranslation,
|
XLATEOBJ* ColorTranslation,
|
||||||
RECTL* OutputRect,
|
RECTL* OutputRect,
|
||||||
RECTL* InputRect,
|
RECTL* InputRect,
|
||||||
|
@ -609,7 +611,7 @@ CallDibStretchBlt(SURFOBJ* OutputObj,
|
||||||
{
|
{
|
||||||
RealBrushOrigin = *BrushOrigin;
|
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
|
// www.osr.com/ddk/graphics/gdifncs_0bs7.htm
|
||||||
|
|
||||||
BYTE clippingType;
|
|
||||||
RECTL CombinedRect;
|
|
||||||
// RECT_ENUM RectEnum;
|
|
||||||
// BOOL EnumMore;
|
|
||||||
SURFGDI* OutputGDI;
|
SURFGDI* OutputGDI;
|
||||||
SURFGDI* InputGDI;
|
SURFGDI* InputGDI;
|
||||||
POINTL InputPoint;
|
POINTL InputPoint;
|
||||||
|
@ -645,30 +643,26 @@ EngStretchBlt(
|
||||||
INTENG_ENTER_LEAVE EnterLeaveDest;
|
INTENG_ENTER_LEAVE EnterLeaveDest;
|
||||||
SURFOBJ* InputObj;
|
SURFOBJ* InputObj;
|
||||||
SURFOBJ* OutputObj;
|
SURFOBJ* OutputObj;
|
||||||
PSTRETCHRECTFUNC BltRectFunc;
|
PSTRETCHRECTFUNC BltRectFunc;
|
||||||
BOOLEAN Ret;
|
BOOLEAN Ret;
|
||||||
RECTL ClipRect;
|
POINTL AdjustedBrushOrigin;
|
||||||
// unsigned i;
|
|
||||||
POINTL Pt;
|
|
||||||
// ULONG Direction;
|
|
||||||
POINTL AdjustedBrushOrigin;
|
|
||||||
|
|
||||||
InputRect.left = prclSrc->left;
|
InputRect.left = prclSrc->left;
|
||||||
InputRect.right = prclSrc->right;
|
InputRect.right = prclSrc->right;
|
||||||
InputRect.top = prclSrc->top;
|
InputRect.top = prclSrc->top;
|
||||||
InputRect.bottom = prclSrc->bottom;
|
InputRect.bottom = prclSrc->bottom;
|
||||||
|
|
||||||
if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
|
if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputPoint.x = InputRect.left + Translate.x;
|
InputPoint.x = InputRect.left + Translate.x;
|
||||||
InputPoint.y = InputRect.top + Translate.y;
|
InputPoint.y = InputRect.top + Translate.y;
|
||||||
|
|
||||||
if (NULL != InputObj)
|
if (NULL != InputObj)
|
||||||
{
|
{
|
||||||
InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
|
InputGDI = (SURFGDI*) AccessInternalObjectFromUserObject(InputObj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -676,44 +670,19 @@ EngStretchBlt(
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputRect = *prclDest;
|
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
|
/* Check for degenerate case: if height or width of OutputRect is 0 pixels there's
|
||||||
nothing to do */
|
nothing to do */
|
||||||
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
|
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
|
||||||
{
|
{
|
||||||
IntEngLeave(&EnterLeaveSource);
|
IntEngLeave(&EnterLeaveSource);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
|
if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj))
|
||||||
{
|
{
|
||||||
IntEngLeave(&EnterLeaveSource);
|
IntEngLeave(&EnterLeaveSource);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputRect.left = prclDest->left + Translate.x;
|
OutputRect.left = prclDest->left + Translate.x;
|
||||||
|
@ -721,28 +690,22 @@ EngStretchBlt(
|
||||||
OutputRect.top = prclDest->top + Translate.y;
|
OutputRect.top = prclDest->top + Translate.y;
|
||||||
OutputRect.bottom = prclDest->bottom + Translate.y;
|
OutputRect.bottom = prclDest->bottom + Translate.y;
|
||||||
|
|
||||||
if(BrushOrigin)
|
if (NULL != BrushOrigin)
|
||||||
{
|
{
|
||||||
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
|
AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
|
||||||
AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
|
AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
AdjustedBrushOrigin = Translate;
|
{
|
||||||
|
AdjustedBrushOrigin = Translate;
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL != OutputObj)
|
if (NULL != OutputObj)
|
||||||
{
|
{
|
||||||
OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
|
OutputGDI = (SURFGDI*)AccessInternalObjectFromUserObject(OutputObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine clipping type
|
if (Mask != NULL)
|
||||||
if (ClipRegion == (CLIPOBJ *) NULL)
|
|
||||||
{
|
|
||||||
clippingType = DC_TRIVIAL;
|
|
||||||
} else {
|
|
||||||
clippingType = ClipRegion->iDComplexity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Mask != NULL)//(0xaacc == Rop4)
|
|
||||||
{
|
{
|
||||||
//BltRectFunc = BltMask;
|
//BltRectFunc = BltMask;
|
||||||
DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
|
DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
|
||||||
|
@ -757,70 +720,9 @@ EngStretchBlt(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch(clippingType)
|
Ret = (*BltRectFunc)(OutputObj, OutputGDI, InputObj, InputGDI, Mask, ClipRegion,
|
||||||
{
|
ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
|
||||||
case DC_TRIVIAL:
|
&AdjustedBrushOrigin, Mode);
|
||||||
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;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IntEngLeave(&EnterLeaveDest);
|
IntEngLeave(&EnterLeaveDest);
|
||||||
IntEngLeave(&EnterLeaveSource);
|
IntEngLeave(&EnterLeaveSource);
|
||||||
|
@ -844,8 +746,6 @@ IntEngStretchBlt(SURFOBJ *DestObj,
|
||||||
BOOLEAN ret;
|
BOOLEAN ret;
|
||||||
SURFGDI *DestGDI;
|
SURFGDI *DestGDI;
|
||||||
SURFGDI *SourceGDI;
|
SURFGDI *SourceGDI;
|
||||||
RECTL OutputRect;
|
|
||||||
RECTL InputRect;
|
|
||||||
COLORADJUSTMENT ca;
|
COLORADJUSTMENT ca;
|
||||||
POINT MaskOrigin;
|
POINT MaskOrigin;
|
||||||
|
|
||||||
|
@ -854,43 +754,19 @@ IntEngStretchBlt(SURFOBJ *DestObj,
|
||||||
MaskOrigin.x = pMaskOrigin->x; MaskOrigin.y = pMaskOrigin->y;
|
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)
|
if (NULL != SourceObj)
|
||||||
{
|
{
|
||||||
SourceGDI = (SURFGDI*) AccessInternalObjectFromUserObject(SourceObj);
|
SourceGDI = (SURFGDI*) AccessInternalObjectFromUserObject(SourceObj);
|
||||||
MouseSafetyOnDrawStart(SourceObj, SourceGDI, InputRect.left, InputRect.top,
|
MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourceRect->left, SourceRect->top,
|
||||||
(InputRect.left + abs(InputRect.right - InputRect.left)),
|
(SourceRect->left + abs(SourceRect->right - SourceRect->left)),
|
||||||
(InputRect.top + abs(InputRect.bottom - InputRect.top)));
|
(SourceRect->top + abs(SourceRect->bottom - SourceRect->top)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No success yet */
|
/* No success yet */
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
|
DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj);
|
||||||
MouseSafetyOnDrawStart(DestObj, DestGDI, OutputRect.left, OutputRect.top,
|
MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top,
|
||||||
OutputRect.right, OutputRect.bottom);
|
DestRect->right, DestRect->bottom);
|
||||||
|
|
||||||
/* Prepare color adjustment */
|
/* Prepare color adjustment */
|
||||||
|
|
||||||
|
@ -902,7 +778,7 @@ IntEngStretchBlt(SURFOBJ *DestObj,
|
||||||
// FIXME: MaskOrigin is always NULL !
|
// FIXME: MaskOrigin is always NULL !
|
||||||
IntLockGDIDriver(DestGDI);
|
IntLockGDIDriver(DestGDI);
|
||||||
ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
ret = DestGDI->StretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
||||||
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
|
&ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
|
||||||
IntUnLockGDIDriver(DestGDI);
|
IntUnLockGDIDriver(DestGDI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,7 +786,7 @@ IntEngStretchBlt(SURFOBJ *DestObj,
|
||||||
{
|
{
|
||||||
// FIXME: see previous fixme
|
// FIXME: see previous fixme
|
||||||
ret = EngStretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
ret = EngStretchBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation,
|
||||||
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, Mode);
|
&ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseSafetyOnDrawEnd(DestObj, DestGDI);
|
MouseSafetyOnDrawEnd(DestObj, DestGDI);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -333,4 +333,123 @@ CLIPOBJ_bEnum(IN CLIPOBJ* ClipObj,
|
||||||
return ClipGDI->EnumPos < ClipGDI->EnumRects.c;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -32,4 +32,13 @@ typedef struct _RECT_ENUM
|
||||||
RECTL arcl[ENUM_RECT_LIMIT];
|
RECTL arcl[ENUM_RECT_LIMIT];
|
||||||
} RECT_ENUM;
|
} 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
|
#endif
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -110,7 +110,8 @@ static BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
RECTL* DestRect, RECTL *SourceRect,
|
RECTL* DestRect, RECTL *SourceRect,
|
||||||
POINTL* MaskOrigin, POINTL BrushOrign,
|
POINTL* MaskOrigin, POINTL BrushOrign,
|
||||||
XLATEOBJ *ColorTranslation, ULONG Mode)
|
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
|
||||||
|
ULONG Mode)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#define TAG_BEZIER TAG('B', 'E', 'Z', 'R') /* bezier */
|
#define TAG_BEZIER TAG('B', 'E', 'Z', 'R') /* bezier */
|
||||||
#define TAG_BITMAP TAG('B', 'T', 'M', 'P') /* bitmap */
|
#define TAG_BITMAP TAG('B', 'T', 'M', 'P') /* bitmap */
|
||||||
#define TAG_PATBLT TAG('P', 'B', 'L', 'T') /* patblt */
|
#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_COORD TAG('C', 'O', 'R', 'D') /* coords */
|
||||||
#define TAG_DC TAG('D', 'C', 'D', 'C') /* dc */
|
#define TAG_DC TAG('D', 'C', 'D', 'C') /* dc */
|
||||||
#define TAG_GDIOBJ TAG('G', 'D', 'I', 'O') /* gdi obj */
|
#define TAG_GDIOBJ TAG('G', 'D', 'I', 'O') /* gdi obj */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue