2004-01-10 14:39:21 +00:00
|
|
|
#include <ntddk.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
#include "../vgaddi.h"
|
|
|
|
#include "../vgavideo/vgavideo.h"
|
|
|
|
#include "brush.h"
|
|
|
|
#include "bitblt.h"
|
|
|
|
|
|
|
|
typedef BOOL (*PFN_VGABlt)(SURFOBJ*, SURFOBJ*, XLATEOBJ*, RECTL*, POINTL*);
|
|
|
|
typedef BOOL STDCALL (*PBLTRECTFUNC)(SURFOBJ* OutputObj,
|
|
|
|
SURFOBJ* InputObj,
|
|
|
|
SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation,
|
|
|
|
RECTL* OutputRect,
|
|
|
|
POINTL* InputPoint,
|
|
|
|
POINTL* MaskOrigin,
|
|
|
|
BRUSHOBJ* Brush,
|
|
|
|
POINTL* BrushOrigin,
|
|
|
|
ROP4 Rop4);
|
|
|
|
|
|
|
|
static BOOL FASTCALL VGADDI_IntersectRect(RECTL* prcDst, RECTL* prcSrc1, RECTL* prcSrc2)
|
|
|
|
{
|
|
|
|
static const RECTL rclEmpty = { 0, 0, 0, 0 };
|
|
|
|
|
|
|
|
prcDst->left = max(prcSrc1->left, prcSrc2->left);
|
|
|
|
prcDst->right = min(prcSrc1->right, prcSrc2->right);
|
|
|
|
|
|
|
|
if (prcDst->left < prcDst->right)
|
|
|
|
{
|
|
|
|
prcDst->top = max(prcSrc1->top, prcSrc2->top);
|
|
|
|
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
|
|
|
|
|
|
|
|
if (prcDst->top < prcDst->bottom) return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
*prcDst = rclEmpty;
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DIB_BltToVGA_Fixed(int x, int y, int w, int h, void *b, int Source_lDelta, int mod);
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect, POINTL *SourcePoint)
|
|
|
|
{
|
|
|
|
LONG dx, dy;
|
|
|
|
|
|
|
|
dx = DestRect->right - DestRect->left;
|
|
|
|
dy = DestRect->bottom - DestRect->top;
|
|
|
|
|
|
|
|
if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
|
|
|
|
{
|
|
|
|
DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy,
|
2005-07-05 00:24:36 +00:00
|
|
|
(PVOID)((ULONG_PTR)Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1)),
|
2004-01-10 14:39:21 +00:00
|
|
|
Source->lDelta, SourcePoint->x % 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Perform color translation */
|
|
|
|
DIB_BltToVGAWithXlate(DestRect->left, DestRect->top, dx, dy,
|
2005-07-05 00:24:36 +00:00
|
|
|
(PVOID)((ULONG_PTR)Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1)),
|
2004-01-10 14:39:21 +00:00
|
|
|
Source->lDelta, ColorTranslation);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-05-08 02:16:32 +00:00
|
|
|
BOOL
|
2004-01-10 14:39:21 +00:00
|
|
|
VGAtoDIB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect, POINTL *SourcePoint)
|
|
|
|
{
|
|
|
|
LONG i, j, dx, dy;
|
|
|
|
BYTE *GDIpos, *initial;
|
2005-05-08 02:16:32 +00:00
|
|
|
|
2004-01-10 14:39:21 +00:00
|
|
|
// Used by the temporary DFB
|
|
|
|
DEVSURF DestDevSurf;
|
|
|
|
|
|
|
|
// FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte)
|
|
|
|
|
2004-07-03 13:45:42 +00:00
|
|
|
GDIpos = Dest->pvScan0 /* + (DestRect->top * Dest->lDelta) + (DestRect->left >> 1) */ ;
|
2004-01-10 14:39:21 +00:00
|
|
|
dx = DestRect->right - DestRect->left;
|
|
|
|
dy = DestRect->bottom - DestRect->top;
|
|
|
|
|
|
|
|
if(ColorTranslation == NULL)
|
|
|
|
{
|
|
|
|
// Prepare a Dest Dev Target and copy from the DFB to the DIB
|
|
|
|
DestDevSurf.NextScan = Dest->lDelta;
|
|
|
|
DestDevSurf.StartBmp = Dest->pvScan0;
|
|
|
|
|
2004-07-03 13:45:42 +00:00
|
|
|
DIB_BltFromVGA(SourcePoint->x, SourcePoint->y, dx, dy, Dest->pvScan0, Dest->lDelta);
|
2004-01-10 14:39:21 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
// Color translation
|
|
|
|
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
|
|
|
|
{
|
|
|
|
initial = GDIpos;
|
|
|
|
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
|
|
|
|
{
|
|
|
|
*GDIpos = XLATEOBJ_iXlate(ColorTranslation, vgaGetPixel(i, j));
|
|
|
|
GDIpos+=1;
|
|
|
|
}
|
|
|
|
GDIpos = initial + Dest->lDelta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-05-08 02:16:32 +00:00
|
|
|
BOOL
|
2004-01-10 14:39:21 +00:00
|
|
|
DFBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect, POINTL *SourcePoint)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
// Do DFBs need color translation??
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
VGAtoDFB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect, POINTL *SourcePoint)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
// Do DFBs need color translation??
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
VGAtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect, POINTL *SourcePoint)
|
|
|
|
{
|
|
|
|
LONG i, i2, j, dx, dy, alterx, altery;
|
|
|
|
//LARGE_INTEGER Start, End; // for performance measurement only
|
|
|
|
static char buf[640];
|
|
|
|
|
|
|
|
// Calculate deltas
|
|
|
|
|
|
|
|
dx = DestRect->right - DestRect->left;
|
|
|
|
dy = DestRect->bottom - DestRect->top;
|
|
|
|
|
|
|
|
alterx = DestRect->left - SourcePoint->x;
|
|
|
|
altery = DestRect->top - SourcePoint->y;
|
|
|
|
|
|
|
|
//KeQueryTickCount ( &Start );
|
|
|
|
|
|
|
|
i = SourcePoint->x;
|
|
|
|
i2 = i + alterx;
|
|
|
|
|
|
|
|
if (SourcePoint->y >= DestRect->top)
|
|
|
|
{
|
|
|
|
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
|
|
|
|
{
|
|
|
|
LONG j2 = j + altery;
|
|
|
|
vgaReadScan ( i, j, dx, buf );
|
|
|
|
vgaWriteScan ( i2, j2, dx, buf );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(j=(SourcePoint->y+dy-1); j>=SourcePoint->y; j--)
|
|
|
|
{
|
|
|
|
LONG j2 = j + altery;
|
|
|
|
vgaReadScan ( i, j, dx, buf );
|
|
|
|
vgaWriteScan ( i2, j2, dx, buf );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//KeQueryTickCount ( &End );
|
|
|
|
//DbgPrint ( "VgaBitBlt timing: %lu\n", (ULONG)(End.QuadPart-Start.QuadPart) );
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
VGADDI_BltBrush(SURFOBJ* Dest, SURFOBJ* Source, SURFOBJ* MaskSurf,
|
|
|
|
XLATEOBJ* ColorTranslation, RECTL* DestRect,
|
|
|
|
POINTL* SourcePoint, POINTL* MaskPoint,
|
|
|
|
BRUSHOBJ* Brush, POINTL* BrushPoint, ROP4 Rop4)
|
|
|
|
{
|
|
|
|
UCHAR SolidColor = 0;
|
2005-07-05 22:35:29 +00:00
|
|
|
LONG Left;
|
|
|
|
LONG Length;
|
2004-01-10 14:39:21 +00:00
|
|
|
PUCHAR Video;
|
|
|
|
UCHAR Mask;
|
2005-07-05 22:35:29 +00:00
|
|
|
INT i, j;
|
2004-01-10 14:39:21 +00:00
|
|
|
ULONG RasterOp = VGA_NORMAL;
|
|
|
|
|
|
|
|
/* Punt brush blts to non-device surfaces. */
|
|
|
|
if (Dest->iType != STYPE_DEVICE)
|
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Punt pattern fills. */
|
2005-02-06 18:27:06 +00:00
|
|
|
if ((GET_OPINDEX_FROM_ROP4(Rop4) == GET_OPINDEX_FROM_ROP3(PATCOPY)
|
2005-05-08 02:16:32 +00:00
|
|
|
|| GET_OPINDEX_FROM_ROP4(Rop4) == GET_OPINDEX_FROM_ROP3(PATINVERT)) &&
|
2004-01-10 14:39:21 +00:00
|
|
|
Brush->iSolidColor == 0xFFFFFFFF)
|
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the brush colour. */
|
2005-02-06 18:27:06 +00:00
|
|
|
switch (GET_OPINDEX_FROM_ROP4(Rop4))
|
2004-01-10 14:39:21 +00:00
|
|
|
{
|
2005-02-06 18:27:06 +00:00
|
|
|
case GET_OPINDEX_FROM_ROP3(PATCOPY): SolidColor = Brush->iSolidColor; break;
|
|
|
|
case GET_OPINDEX_FROM_ROP3(PATINVERT): SolidColor = Brush->iSolidColor; RasterOp = VGA_XOR; break;
|
|
|
|
case GET_OPINDEX_FROM_ROP3(WHITENESS): SolidColor = 0xF; break;
|
|
|
|
case GET_OPINDEX_FROM_ROP3(BLACKNESS): SolidColor = 0x0; break;
|
|
|
|
case GET_OPINDEX_FROM_ROP3(DSTINVERT): SolidColor = 0xF; RasterOp = VGA_XOR; break;
|
2004-01-10 14:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Select write mode 3. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x03);
|
|
|
|
|
|
|
|
/* Setup set/reset register. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x00);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, (UCHAR)SolidColor);
|
|
|
|
|
|
|
|
/* Enable writes to all pixels. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
|
|
|
|
|
|
|
|
/* Set up data rotate. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, RasterOp);
|
2005-05-08 02:16:32 +00:00
|
|
|
|
2004-01-10 14:39:21 +00:00
|
|
|
/* Fill any pixels on the left which don't fall into a full row of eight. */
|
|
|
|
if ((DestRect->left % 8) != 0)
|
|
|
|
{
|
|
|
|
/* Disable writes to pixels outside of the destination rectangle. */
|
|
|
|
Mask = (1 << (8 - (DestRect->left % 8))) - 1;
|
|
|
|
if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
|
|
|
|
{
|
|
|
|
Mask &= ~((1 << (8 - (DestRect->right % 8))) - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the same color to each pixel. */
|
|
|
|
Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->left >> 3);
|
|
|
|
for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
|
|
|
|
{
|
|
|
|
(VOID)READ_REGISTER_UCHAR(Video);
|
|
|
|
WRITE_REGISTER_UCHAR(Video, Mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Have we finished. */
|
|
|
|
if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
|
|
|
|
{
|
|
|
|
/* Restore write mode 2. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
|
|
|
|
|
|
|
|
/* Set up data rotate. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2005-05-08 02:16:32 +00:00
|
|
|
}
|
2004-01-10 14:39:21 +00:00
|
|
|
|
|
|
|
/* Fill any whole rows of eight pixels. */
|
|
|
|
Left = (DestRect->left + 7) & ~0x7;
|
|
|
|
Length = (DestRect->right >> 3) - (Left >> 3);
|
|
|
|
for (i = DestRect->top; i < DestRect->bottom; i++)
|
|
|
|
{
|
|
|
|
Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
|
|
|
|
for (j = 0; j < Length; j++, Video++)
|
|
|
|
{
|
2004-04-08 15:45:18 +00:00
|
|
|
#if 0
|
2004-01-10 14:39:21 +00:00
|
|
|
(VOID)READ_REGISTER_UCHAR(Video);
|
|
|
|
WRITE_REGISTER_UCHAR(Video, 0xFF);
|
2004-04-08 15:45:18 +00:00
|
|
|
#else
|
|
|
|
char volatile Temp = *Video;
|
|
|
|
Temp |= 0;
|
|
|
|
*Video = 0xFF;
|
|
|
|
#endif
|
2004-01-10 14:39:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill any pixels on the right which don't fall into a complete row. */
|
|
|
|
if ((DestRect->right % 8) != 0)
|
|
|
|
{
|
|
|
|
/* Disable writes to pixels outside the destination rectangle. */
|
|
|
|
Mask = ~((1 << (8 - (DestRect->right % 8))) - 1);
|
|
|
|
|
|
|
|
Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->right >> 3);
|
|
|
|
for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
|
|
|
|
{
|
|
|
|
(VOID)READ_REGISTER_UCHAR(Video);
|
|
|
|
WRITE_REGISTER_UCHAR(Video, Mask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Restore write mode 2. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
|
|
|
|
|
|
|
|
/* Set up data rotate. */
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
|
|
|
|
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
VGADDI_BltSrc(SURFOBJ* Dest, SURFOBJ* Source, SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation, RECTL* DestRect, POINTL* SourcePoint,
|
|
|
|
POINTL* MaskOrigin, BRUSHOBJ* Brush, POINTL* BrushOrigin, ROP4 Rop4)
|
|
|
|
{
|
|
|
|
PFN_VGABlt BltOperation;
|
|
|
|
ULONG SourceType;
|
|
|
|
|
|
|
|
SourceType = Source->iType;
|
|
|
|
|
|
|
|
if (SourceType == STYPE_BITMAP && Dest->iType == STYPE_DEVICE)
|
|
|
|
{
|
|
|
|
BltOperation = DIBtoVGA;
|
|
|
|
}
|
|
|
|
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP)
|
|
|
|
{
|
|
|
|
BltOperation = VGAtoDIB;
|
|
|
|
}
|
|
|
|
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE)
|
|
|
|
{
|
|
|
|
BltOperation = VGAtoVGA;
|
2005-05-08 02:16:32 +00:00
|
|
|
}
|
2004-01-10 14:39:21 +00:00
|
|
|
else if (SourceType == STYPE_DEVBITMAP && Dest->iType == STYPE_DEVICE)
|
|
|
|
{
|
|
|
|
BltOperation = DFBtoVGA;
|
2005-05-08 02:16:32 +00:00
|
|
|
}
|
2004-01-10 14:39:21 +00:00
|
|
|
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVBITMAP)
|
|
|
|
{
|
|
|
|
BltOperation = VGAtoDFB;
|
2005-05-08 02:16:32 +00:00
|
|
|
}
|
2004-01-10 14:39:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Punt blts not involving a device or a device-bitmap. */
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
BltOperation(Dest, Source, ColorTranslation, DestRect, SourcePoint);
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
VGADDI_BltMask(SURFOBJ* Dest, SURFOBJ* Source, SURFOBJ* Mask,
|
|
|
|
XLATEOBJ* ColorTranslation, RECTL* DestRect,
|
|
|
|
POINTL* SourcePoint, POINTL* MaskPoint, BRUSHOBJ* Brush,
|
|
|
|
POINTL* BrushPoint, ROP4 Rop4)
|
|
|
|
{
|
|
|
|
LONG i, j, dx, dy, c8;
|
|
|
|
BYTE *tMask, *lMask;
|
|
|
|
|
|
|
|
dx = DestRect->right - DestRect->left;
|
|
|
|
dy = DestRect->bottom - DestRect->top;
|
|
|
|
|
|
|
|
if (ColorTranslation == NULL)
|
|
|
|
{
|
|
|
|
if (Mask != NULL)
|
|
|
|
{
|
2004-07-03 13:45:42 +00:00
|
|
|
tMask = Mask->pvScan0;
|
2004-01-10 14:39:21 +00:00
|
|
|
for (j=0; j<dy; j++)
|
|
|
|
{
|
|
|
|
lMask = tMask;
|
|
|
|
c8 = 0;
|
|
|
|
for (i=0; i<dx; i++)
|
|
|
|
{
|
|
|
|
if((*lMask & maskbit[c8]) != 0)
|
|
|
|
{
|
|
|
|
vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
|
|
|
|
}
|
|
|
|
c8++;
|
|
|
|
if(c8 == 8) { lMask++; c8=0; }
|
|
|
|
}
|
|
|
|
tMask += Mask->lDelta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
DrvBitBlt(SURFOBJ *Dest,
|
|
|
|
SURFOBJ *Source,
|
|
|
|
SURFOBJ *Mask,
|
|
|
|
CLIPOBJ *Clip,
|
|
|
|
XLATEOBJ *ColorTranslation,
|
|
|
|
RECTL *DestRect,
|
|
|
|
POINTL *SourcePoint,
|
|
|
|
POINTL *MaskPoint,
|
|
|
|
BRUSHOBJ *Brush,
|
|
|
|
POINTL *BrushPoint,
|
|
|
|
ROP4 rop4)
|
|
|
|
{
|
|
|
|
PBLTRECTFUNC BltRectFunc;
|
|
|
|
RECTL CombinedRect;
|
2004-07-03 17:40:27 +00:00
|
|
|
BOOL Ret = FALSE;
|
2004-01-10 14:39:21 +00:00
|
|
|
RECT_ENUM RectEnum;
|
|
|
|
BOOL EnumMore;
|
|
|
|
unsigned i;
|
|
|
|
POINTL Pt;
|
|
|
|
ULONG Direction;
|
|
|
|
|
|
|
|
switch (rop4)
|
|
|
|
{
|
2005-02-06 18:27:06 +00:00
|
|
|
case ROP3_TO_ROP4(BLACKNESS):
|
|
|
|
case ROP3_TO_ROP4(PATCOPY):
|
|
|
|
case ROP3_TO_ROP4(WHITENESS):
|
|
|
|
case ROP3_TO_ROP4(PATINVERT):
|
|
|
|
case ROP3_TO_ROP4(DSTINVERT):
|
2004-01-10 14:39:21 +00:00
|
|
|
BltRectFunc = VGADDI_BltBrush;
|
|
|
|
break;
|
|
|
|
|
2005-02-06 18:27:06 +00:00
|
|
|
case ROP3_TO_ROP4(SRCCOPY):
|
2004-01-10 14:39:21 +00:00
|
|
|
if (BMF_4BPP == Source->iBitmapFormat && BMF_4BPP == Dest->iBitmapFormat)
|
|
|
|
{
|
|
|
|
BltRectFunc = VGADDI_BltSrc;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2005-02-06 18:27:06 +00:00
|
|
|
case R4_MASK:
|
2004-01-10 14:39:21 +00:00
|
|
|
BltRectFunc = VGADDI_BltMask;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(NULL == Clip ? DC_TRIVIAL : Clip->iDComplexity)
|
|
|
|
{
|
|
|
|
case DC_TRIVIAL:
|
|
|
|
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, DestRect,
|
|
|
|
SourcePoint, MaskPoint, Brush, BrushPoint,
|
|
|
|
rop4);
|
|
|
|
break;
|
|
|
|
case DC_RECT:
|
|
|
|
// Clip the blt to the clip rectangle
|
|
|
|
VGADDI_IntersectRect(&CombinedRect, DestRect, &(Clip->rclBounds));
|
|
|
|
Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
|
|
|
|
Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
|
|
|
|
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
|
|
|
|
&Pt, MaskPoint, Brush, BrushPoint,
|
|
|
|
rop4);
|
|
|
|
break;
|
|
|
|
case DC_COMPLEX:
|
|
|
|
Ret = TRUE;
|
|
|
|
if (Dest == Source)
|
|
|
|
{
|
|
|
|
if (DestRect->top <= SourcePoint->y)
|
|
|
|
{
|
|
|
|
Direction = DestRect->left < SourcePoint->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Direction = DestRect->left < SourcePoint->x ? CD_RIGHTUP : CD_LEFTUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Direction = CD_ANY;
|
|
|
|
}
|
|
|
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, 0);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
|
|
|
|
|
|
|
for (i = 0; i < RectEnum.c; i++)
|
|
|
|
{
|
|
|
|
VGADDI_IntersectRect(&CombinedRect, DestRect, RectEnum.arcl + i);
|
|
|
|
Pt.x = SourcePoint->x + CombinedRect.left - DestRect->left;
|
|
|
|
Pt.y = SourcePoint->y + CombinedRect.top - DestRect->top;
|
|
|
|
Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
|
|
|
|
&Pt, MaskPoint, Brush, BrushPoint, rop4) &&
|
|
|
|
Ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (EnumMore);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|