mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
Implemented DrvCopybits
Minor fixes svn path=/trunk/; revision=1116
This commit is contained in:
parent
5b7a3113d5
commit
04a84d5ab8
11 changed files with 1078 additions and 87 deletions
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* entry.c
|
||||
*
|
||||
* $Revision: 1.4 $
|
||||
* $Revision: 1.5 $
|
||||
* $Author: jfilby $
|
||||
* $Date: 2000/04/03 19:55:32 $
|
||||
* $Date: 2000/04/10 20:17:32 $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -44,6 +44,9 @@ BOOL VGADDIBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask,
|
|||
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
||||
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
|
||||
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4);
|
||||
BOOL VGADDICopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
||||
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
||||
PRECTL DestRect, PPOINTL SourcePoint);
|
||||
|
||||
DRVFN FuncList[] =
|
||||
{
|
||||
|
@ -58,11 +61,11 @@ DRVFN FuncList[] =
|
|||
{INDEX_DrvLineTo, (PFN) VGADDILineTo},
|
||||
{INDEX_DrvPaint, (PFN) VGADDIPaint},
|
||||
{INDEX_DrvBitBlt, (PFN) VGADDIBitBlt},
|
||||
// {INDEX_DrvCopyBits, (PFN) VGADDICopyBits},
|
||||
|
||||
#if 0
|
||||
/* Optional Display driver functions */
|
||||
{INDEX_, (PFN) },
|
||||
{INDEX_DrvCopyBits, (PFN) VGADDICopyBits},
|
||||
{INDEX_DescribePixelFormat, (PFN) VGADDIDescribePixelFormat},
|
||||
{INDEX_DrvDitherColor, (PFN) VGADDIDitherColor},
|
||||
{INDEX_DrvFillPath, (PFN) VGADDIFillPath},
|
||||
|
@ -340,8 +343,6 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev)
|
|||
DHSURF dhsurf;
|
||||
HSURF hsurf;
|
||||
|
||||
DbgPrint("DrvEnableSurface..\n");
|
||||
|
||||
// Initialize the VGA
|
||||
if (!InitVGA(ppdev, TRUE))
|
||||
{
|
||||
|
@ -379,8 +380,6 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev)
|
|||
goto error_clean;
|
||||
} BANKING CODE UNIMPLEMENTED */
|
||||
|
||||
DbgPrint("Calling EngCreateDeviceSurface..\n");
|
||||
|
||||
if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizeSurf, BMF_4BPP)) ==
|
||||
(HSURF)0)
|
||||
{
|
||||
|
@ -388,11 +387,10 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev)
|
|||
EngDebugPrint("VGADDI:", "EngCreateDeviceSurface call failed\n", 0);
|
||||
goto error_clean;
|
||||
}
|
||||
DbgPrint("init saved bits.. ");
|
||||
InitSavedBits(ppdev);
|
||||
DbgPrint("successful\n");
|
||||
|
||||
if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO))
|
||||
InitSavedBits(ppdev);
|
||||
|
||||
if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO | HOOK_COPYBITS))
|
||||
{
|
||||
EngDebugPrint("VGADDI:", "Successfully associated surface\n", 0);
|
||||
ppdev->SurfHandle = hsurf;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.4 2000/04/03 19:55:32 jfilby Exp $
|
||||
# $Id: makefile,v 1.5 2000/04/10 20:17:32 jfilby Exp $
|
||||
#
|
||||
# Makefile for ReactOS vgaddi.dll
|
||||
#
|
||||
|
@ -19,7 +19,7 @@ endif
|
|||
all: $(DLLTARGET)
|
||||
|
||||
MAIN_OBJECTS = main/enable.o
|
||||
OTHER_OBJECTS = objects/screen.o objects/lineto.o objects/paint.o objects/bitblt.o vgavideo/vgavideo.o
|
||||
OTHER_OBJECTS = objects/screen.o objects/lineto.o objects/paint.o objects/bitblt.o objects/copybits.o vgavideo/vgavideo.o
|
||||
RESOURCE_OBJECTS = $(TARGET).coff
|
||||
|
||||
OBJECTS = $(MAIN_OBJECTS) $(OTHER_OBJECTS) $(RESOURCE_OBJECTS)
|
||||
|
|
|
@ -15,7 +15,7 @@ BOOL GDItoVGA(
|
|||
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
|
||||
RECTL *DestRect, POINTL *SourcePoint)
|
||||
{
|
||||
ULONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, BPP;
|
||||
LONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, BPP;
|
||||
BYTE *GDIpos, *initial;
|
||||
|
||||
BPP = bytesPerPixel(Source->iBitmapFormat);
|
||||
|
@ -36,7 +36,6 @@ BOOL GDItoVGA(
|
|||
{
|
||||
RtlCopyMemory(&RGBulong, GDIpos, BPP);
|
||||
idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong);
|
||||
|
||||
vgaPutPixel(i+alterx, j+altery, idxColor);
|
||||
GDIpos+=BPP;
|
||||
}
|
||||
|
@ -48,32 +47,48 @@ BOOL VGAtoGDI(
|
|||
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
|
||||
RECTL *DestRect, POINTL *SourcePoint)
|
||||
{
|
||||
ULONG i, j, dx, dy, idxColor, RGBulong, BPP;
|
||||
BYTE *GDIpos, *initial;
|
||||
LONG i, j, dx, dy, RGBulong, BPP;
|
||||
BYTE *GDIpos, *initial, idxColor;
|
||||
|
||||
// FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte)
|
||||
|
||||
BPP = bytesPerPixel(Dest->iBitmapFormat);
|
||||
GDIpos = Dest->pvBits +
|
||||
DestRect->top * Dest->lDelta + DestRect->left;
|
||||
(DestRect->top * Dest->lDelta) + (DestRect->left * BPP);
|
||||
|
||||
dx = DestRect->right - DestRect->left;
|
||||
dy = DestRect->bottom - DestRect->top;
|
||||
|
||||
if(ColorTranslation == NULL)
|
||||
{
|
||||
// No color translation necessary, we assume BPP = 1
|
||||
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
|
||||
{
|
||||
initial = GDIpos;
|
||||
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
|
||||
{
|
||||
idxColor = vgaGetPixel(i, j);
|
||||
RtlCopyMemory(GDIpos, &idxColor, 1);
|
||||
GDIpos++;
|
||||
}
|
||||
GDIpos = initial + Dest->lDelta;
|
||||
}
|
||||
} else {
|
||||
// Color translation
|
||||
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
|
||||
{
|
||||
initial = GDIpos;
|
||||
|
||||
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
|
||||
{
|
||||
idxColor = vgaGetPixel(i, j);
|
||||
|
||||
RGBulong = XLATEOBJ_iXlate(ColorTranslation, idxColor);
|
||||
RtlCopyMemory(GDIpos, &RGBulong, BPP);
|
||||
|
||||
GDIpos+=BPP;
|
||||
}
|
||||
GDIpos = initial + Dest->lDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL DFBtoVGA(
|
||||
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
|
||||
|
@ -200,7 +215,7 @@ BOOL VGADDIBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask,
|
|||
{
|
||||
// FIXME: Intersect clip rectangle
|
||||
|
||||
BltOperation(Dest, Source, ColorTranslation, Mask,
|
||||
BltOperation(Dest, Source, Mask, ColorTranslation,
|
||||
DestRect, SourcePoint);
|
||||
} else {
|
||||
|
||||
|
|
859
reactos/drivers/dd/vga/display/objects/copybits.c
Normal file
859
reactos/drivers/dd/vga/display/objects/copybits.c
Normal file
|
@ -0,0 +1,859 @@
|
|||
#include <ddk/winddi.h>
|
||||
#include <internal\i386\io.h>
|
||||
|
||||
#include "..\vgaddi.h"
|
||||
#include "..\vgavideo\vgavideo.h"
|
||||
|
||||
// FIXME: There's a lot of redundancy in here -- break into functions
|
||||
// FIXME: All functions involving the screen use terribly slow vgaPutPixel -- use something better
|
||||
|
||||
VOID Screen2Screen(PDEVSURF PDSurf, RECTL *DestRect, POINTL *SourcePoint,
|
||||
ULONG iCopyDir)
|
||||
{
|
||||
ULONG i, j, spx, spy;
|
||||
spy = SourcePoint->y;
|
||||
|
||||
// FIXME: Right now assumes top->down and left->right
|
||||
|
||||
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||
{
|
||||
spx = SourcePoint->x;
|
||||
for(i=DestRect->left; i<DestRect->right; i++)
|
||||
{
|
||||
vgaPutPixel(spx, spy, vgaGetPixel(i, j));
|
||||
spx++;
|
||||
}
|
||||
spy++;
|
||||
}
|
||||
}
|
||||
|
||||
VOID CopyRect4BPP(PDEVSURF DestSurf, PDEVSURF SourceSurf, RECTL *DestRect,
|
||||
POINTL *SourcePoint)
|
||||
{
|
||||
ULONG i, j, Width, spy;
|
||||
spy = SourcePoint->y;
|
||||
Width = DestRect->right - DestRect->left;
|
||||
|
||||
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||
{
|
||||
RtlCopyMemory(DestSurf->StartBmp+DestSurf->NextScan*j+DestRect->left,
|
||||
SourceSurf->StartBmp+SourceSurf->NextScan*j+SourcePoint->x,
|
||||
Width);
|
||||
spy++;
|
||||
}
|
||||
}
|
||||
|
||||
VOID DFB2DIB(PDEVSURF DestSurf, PDEVSURF SourceSurf, RECTL *DestRect,
|
||||
POINTL *SourcePoint)
|
||||
{
|
||||
CopyRect4BPP(DestSurf, SourceSurf, DestRect, SourcePoint);
|
||||
}
|
||||
|
||||
VOID DFB2DFB(PDEVSURF DestSurf, PDEVSURF SourceSurf, RECTL *DestRect,
|
||||
POINTL *SourcePoint)
|
||||
{
|
||||
CopyRect4BPP(DestSurf, SourceSurf, DestRect, SourcePoint);
|
||||
}
|
||||
|
||||
#define DFB_TARGET 0
|
||||
#define VGA_TARGET 1
|
||||
|
||||
VOID DIB2VGA(PDEVSURF DestSurf, PDEVSURF SourceSurf,
|
||||
RECTL *DestRect, POINTL *SourcePoint, UCHAR *ConversionTables,
|
||||
BOOL DFBorVGAtarget)
|
||||
{
|
||||
ULONG i, j, spx, spy;
|
||||
BYTE c;
|
||||
spy = SourcePoint->y;
|
||||
|
||||
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||
{
|
||||
spx = SourcePoint->x;
|
||||
for(i=DestRect->left; i<DestRect->right; i++)
|
||||
{
|
||||
if(DFBorVGAtarget == DFB_TARGET)
|
||||
{
|
||||
c = vgaGetPixel(spx, spy);
|
||||
RtlCopyMemory(DestSurf->StartBmp+j*DestSurf->NextScan+i, c, 1);
|
||||
} else
|
||||
{
|
||||
RtlCopyMemory(c, SourceSurf->StartBmp+j*SourceSurf->NextScan+i, 1);
|
||||
vgaPutPixel(spx, spy, c);
|
||||
}
|
||||
spx++;
|
||||
}
|
||||
spy++;
|
||||
}
|
||||
}
|
||||
|
||||
VOID DFB2VGA(DEVSURF *DestSurf, DEVSURF *SourceSurf, RECTL *DestRect,
|
||||
POINTL *SourcePoint)
|
||||
{
|
||||
DIB2VGA(DestSurf, SourceSurf, DestRect, SourcePoint, NULL, VGA_TARGET);
|
||||
}
|
||||
|
||||
|
||||
VOID VGA2DIB(DEVSURF *DestSurf, ULONG xSource, ULONG ySource,
|
||||
PVOID DestScan0, ULONG left, ULONG top, ULONG width,
|
||||
ULONG height, ULONG lDelta, ULONG Format, ULONG *Conversion)
|
||||
{
|
||||
ULONG i, j, spx, spy, right = left + width, bottom = top + height;
|
||||
BYTE c;
|
||||
spy = ySource;
|
||||
|
||||
for (j=top; j<bottom; j++)
|
||||
{
|
||||
spx = xSource;
|
||||
for(i=left; i<right; i++)
|
||||
{
|
||||
c = vgaGetPixel(spx, spy);
|
||||
RtlCopyMemory(DestSurf->StartBmp+j*DestSurf->NextScan+i, c, 1);
|
||||
spx++;
|
||||
}
|
||||
spy++;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL VGADDICopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
||||
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
||||
PRECTL DestRect, PPOINTL SourcePoint)
|
||||
{
|
||||
PDEVSURF pdsurf; // Pointer to a device surface
|
||||
|
||||
LONG lDelta; // Delta to next scan of destination
|
||||
PVOID pjDstScan0; // Pointer to scan 0 of destination DIB
|
||||
ULONG *pulXlate; // Pointer to color xlate vector
|
||||
BOOL EnumMore; // Clip continuation flag
|
||||
ULONG ircl; // Clip enumeration rectangle index
|
||||
RECT_ENUM cben; // Clip enumerator
|
||||
RECTL TempRect;
|
||||
PRECTL PRect;
|
||||
POINTL TempPoint;
|
||||
DEVSURF TempDSurf;
|
||||
PDEVSURF SurfDest; // Pointer for target
|
||||
PDEVSURF SurfSource; // Pointer for source if present
|
||||
INT iCopyDir;
|
||||
RECT_ENUM RectEnum; // Clip enumerator
|
||||
BYTE jClipping;
|
||||
UCHAR *pucDIB4ToVGAConvTables;
|
||||
ULONG ulWidth;
|
||||
ULONG ulNumSlices;
|
||||
ULONG ulRight;
|
||||
ULONG x;
|
||||
|
||||
// If translation is XO_TRIVIAL then no translation is required
|
||||
if(ColorTranslation && (ColorTranslation->flXlate & XO_TRIVIAL))
|
||||
{
|
||||
ColorTranslation = NULL;
|
||||
}
|
||||
|
||||
// If the destination is a device managed bitmap give it to VGADDIBitBlt
|
||||
if(ColorTranslation &&
|
||||
((Dest->iType == STYPE_DEVICE) || (Dest->iType == STYPE_DEVBITMAP)))
|
||||
{
|
||||
return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL,
|
||||
Clip, ColorTranslation,
|
||||
DestRect, SourcePoint,
|
||||
(POINTL *)NULL, (BRUSHOBJ *)NULL, (POINTL *)NULL,
|
||||
0x0000CCCC));
|
||||
}
|
||||
|
||||
if ((Dest->iType == STYPE_DEVICE) && (Source->iType == STYPE_DEVICE)) {
|
||||
SurfDest = (PDEVSURF) Dest->dhsurf;
|
||||
SurfSource = (PDEVSURF) Source->dhsurf;
|
||||
|
||||
if (Clip == (CLIPOBJ *) NULL)
|
||||
{
|
||||
jClipping = DC_TRIVIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
jClipping = Clip->iDComplexity;
|
||||
}
|
||||
|
||||
|
||||
if (SourcePoint->y >= DestRect->top) {
|
||||
if (SourcePoint->x >= DestRect->left) {
|
||||
iCopyDir = CD_RIGHTDOWN;
|
||||
} else {
|
||||
iCopyDir = CD_LEFTDOWN;
|
||||
}
|
||||
} else {
|
||||
if (SourcePoint->x >= DestRect->left) {
|
||||
iCopyDir = CD_RIGHTUP;
|
||||
} else {
|
||||
iCopyDir = CD_LEFTUP;
|
||||
}
|
||||
}
|
||||
|
||||
switch(jClipping) {
|
||||
|
||||
case DC_TRIVIAL:
|
||||
Screen2Screen(SurfDest, DestRect, SourcePoint, iCopyDir);
|
||||
break;
|
||||
|
||||
case DC_RECT:
|
||||
if (!VGADDIIntersectRect(&TempRect, DestRect,
|
||||
&Clip->rclBounds))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
|
||||
Screen2Screen(SurfDest, &TempRect, &TempPoint, iCopyDir);
|
||||
break;
|
||||
|
||||
case DC_COMPLEX:
|
||||
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
||||
iCopyDir, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum),
|
||||
(PVOID)&RectEnum);
|
||||
|
||||
PRect = RectEnum.arcl;
|
||||
for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++) {
|
||||
|
||||
VGADDIIntersectRect(PRect, PRect, DestRect);
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left -
|
||||
DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top -
|
||||
DestRect->top;
|
||||
Screen2Screen(SurfDest, PRect, &TempPoint, iCopyDir);
|
||||
}
|
||||
} while(EnumMore);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Device managed to standard bitmap
|
||||
if ((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_BITMAP))
|
||||
{
|
||||
switch(Dest->iBitmapFormat)
|
||||
{
|
||||
case BMF_4BPP:
|
||||
if (ColorTranslation == NULL)
|
||||
{
|
||||
// Make just enough of a fake DEVSURF for the dest so that
|
||||
// the DFB to DIB code can work
|
||||
|
||||
TempDSurf.NextScan = Dest->lDelta;
|
||||
TempDSurf.StartBmp = Dest->pvScan0;
|
||||
|
||||
if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL))
|
||||
{
|
||||
ulWidth = DestRect->right - DestRect->left;
|
||||
if (ulWidth <= MAX_SCAN_WIDTH)
|
||||
{
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
DestRect, SourcePoint);
|
||||
} else {
|
||||
TempRect.left = DestRect->left;
|
||||
TempRect.right = DestRect->right;
|
||||
TempRect.top = DestRect->top;
|
||||
TempRect.bottom = DestRect->bottom;
|
||||
|
||||
// cut rect into slices MAX_SCAN_WIDTH wide
|
||||
ulRight = TempRect.right; // save right edge
|
||||
TempRect.right = TempRect.left+MAX_SCAN_WIDTH;
|
||||
ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH;
|
||||
for (x=0; x<ulNumSlices-1; x++)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
TempRect.left = TempRect.right;
|
||||
TempRect.right += MAX_SCAN_WIDTH;
|
||||
}
|
||||
TempRect.right = ulRight;
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
}
|
||||
}
|
||||
else if (Clip->iDComplexity == DC_RECT)
|
||||
{
|
||||
if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds))
|
||||
{
|
||||
ulWidth = TempRect.right - TempRect.left;
|
||||
|
||||
if (ulWidth <= MAX_SCAN_WIDTH)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
} else {
|
||||
// cut rect into slices MAX_SCAN_WIDTH wide
|
||||
ulRight = TempRect.right; // save right edge
|
||||
TempRect.right = TempRect.left+MAX_SCAN_WIDTH;
|
||||
ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH;
|
||||
for (x=0; x<ulNumSlices-1; x++)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
TempRect.left = TempRect.right;
|
||||
TempRect.right += MAX_SCAN_WIDTH;
|
||||
}
|
||||
TempRect.right = ulRight;
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
} else {
|
||||
// DC_COMPLEX:
|
||||
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
||||
CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum),
|
||||
(PVOID) &RectEnum);
|
||||
PRect = RectEnum.arcl;
|
||||
for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++)
|
||||
{
|
||||
VGADDIIntersectRect(PRect,PRect,DestRect);
|
||||
ulWidth = PRect->right - PRect->left;
|
||||
|
||||
if (ulWidth <= MAX_SCAN_WIDTH)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
} else {
|
||||
// cut rect into slices MAX_SCAN_WIDTH wide
|
||||
ulRight = PRect->right; // save right edge
|
||||
PRect->right = PRect->left+MAX_SCAN_WIDTH;
|
||||
ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH;
|
||||
for (x=0; x<ulNumSlices-1; x++)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
PRect, &TempPoint);
|
||||
PRect->left = PRect->right;
|
||||
PRect->right += MAX_SCAN_WIDTH;
|
||||
}
|
||||
PRect->right = ulRight;
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
DFB2DIB(&TempDSurf, (PDEVSURF) Source->dhsurf,
|
||||
PRect, &TempPoint);
|
||||
}
|
||||
}
|
||||
} while(EnumMore);
|
||||
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Device managed to device managed
|
||||
if ((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVBITMAP)) {
|
||||
|
||||
if (Source==Dest)
|
||||
{
|
||||
TempRect.top = SourcePoint->y;
|
||||
TempRect.left = SourcePoint->x;
|
||||
TempRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top);
|
||||
TempRect.right = SourcePoint->x + (DestRect->right - DestRect->left);
|
||||
|
||||
if (DestRect->top >= SourcePoint->y)
|
||||
{
|
||||
if (VGADDIIntersectRect(&TempRect,&TempRect,DestRect))
|
||||
{
|
||||
return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL,
|
||||
Clip, ColorTranslation,
|
||||
DestRect, SourcePoint,
|
||||
(POINTL *)NULL, (BRUSHOBJ *)NULL,
|
||||
(POINTL *)NULL, 0x0000CCCC));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ColorTranslation == NULL)
|
||||
{
|
||||
if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL))
|
||||
{
|
||||
DFB2DFB((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf,
|
||||
DestRect, SourcePoint);
|
||||
} else if (Clip->iDComplexity == DC_RECT)
|
||||
{
|
||||
if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds))
|
||||
{
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
|
||||
DFB2DFB((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
}
|
||||
return(TRUE);
|
||||
} else {
|
||||
// DC_COMPLEX:
|
||||
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
||||
CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), (PVOID)&RectEnum);
|
||||
PRect = RectEnum.arcl;
|
||||
for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++)
|
||||
{
|
||||
VGADDIIntersectRect(PRect,PRect,DestRect);
|
||||
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
|
||||
DFB2DFB((PDEVSURF)Dest->dhsurf, (PDEVSURF)Source->dhsurf,
|
||||
PRect, &TempPoint);
|
||||
}
|
||||
} while(EnumMore);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Device managed to screen
|
||||
if((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVICE))
|
||||
{
|
||||
if(ColorTranslation == NULL)
|
||||
{
|
||||
if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL))
|
||||
{
|
||||
DFB2VGA((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf, DestRect,
|
||||
SourcePoint);
|
||||
} else if (Clip->iDComplexity == DC_RECT)
|
||||
{
|
||||
if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds))
|
||||
{
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
|
||||
DFB2VGA((PDEVSURF) Dest->dhsurf, (PDEVSURF) Source->dhsurf,
|
||||
&TempRect, &TempPoint);
|
||||
}
|
||||
return(TRUE);
|
||||
} else {
|
||||
// DC_COMPLEX:
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), (PVOID)&RectEnum);
|
||||
PRect = RectEnum.arcl;
|
||||
for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++)
|
||||
{
|
||||
VGADDIIntersectRect(PRect,PRect,DestRect);
|
||||
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
|
||||
DFB2VGA((PDEVSURF)Dest->dhsurf, (PDEVSURF)Source->dhsurf,
|
||||
PRect, &TempPoint);
|
||||
}
|
||||
} while(EnumMore);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Standard bitmap to device managed
|
||||
if ((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVBITMAP))
|
||||
{
|
||||
switch(Source->iBitmapFormat)
|
||||
{
|
||||
case BMF_4BPP:
|
||||
if (ColorTranslation == NULL)
|
||||
{
|
||||
pucDIB4ToVGAConvTables =
|
||||
((PDEVSURF) Dest->dhsurf)->ppdev->
|
||||
pucDIB4ToVGAConvTables;
|
||||
|
||||
// Make just enough of a fake DEVSURF for the source so that
|
||||
// the DIB to DFB code can work
|
||||
|
||||
TempDSurf.NextScan = Source->lDelta;
|
||||
TempDSurf.StartBmp = Source->pvScan0;
|
||||
|
||||
// Clip as needed
|
||||
|
||||
if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL))
|
||||
{
|
||||
ulWidth = DestRect->right - DestRect->left;
|
||||
|
||||
if (ulWidth <= MAX_SCAN_WIDTH)
|
||||
{
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, DestRect,
|
||||
SourcePoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
} else {
|
||||
TempRect.left = DestRect->left;
|
||||
TempRect.right = DestRect->right;
|
||||
TempRect.top = DestRect->top;
|
||||
TempRect.bottom = DestRect->bottom;
|
||||
|
||||
// cut rect into slices MAX_SCAN_WIDTH wide
|
||||
ulRight = TempRect.right; // save right edge
|
||||
TempRect.right = TempRect.left+MAX_SCAN_WIDTH;
|
||||
ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH;
|
||||
for (x=0; x<ulNumSlices-1; x++)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
&TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
TempRect.left = TempRect.right;
|
||||
TempRect.right += MAX_SCAN_WIDTH;
|
||||
}
|
||||
TempRect.right = ulRight;
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
&TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
}
|
||||
}
|
||||
else if (Clip->iDComplexity == DC_RECT)
|
||||
{
|
||||
if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds))
|
||||
{
|
||||
ulWidth = TempRect.right - TempRect.left;
|
||||
|
||||
if (ulWidth <= MAX_SCAN_WIDTH)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
&TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
} else {
|
||||
// cut rect into slices MAX_SCAN_WIDTH wide
|
||||
ulRight = TempRect.right; // save right edge
|
||||
TempRect.right = TempRect.left+MAX_SCAN_WIDTH;
|
||||
ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH;
|
||||
for (x=0; x<ulNumSlices-1; x++)
|
||||
{
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
&TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
TempRect.left = TempRect.right;
|
||||
TempRect.right += MAX_SCAN_WIDTH;
|
||||
}
|
||||
TempRect.right = ulRight;
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
&TempRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
} else {
|
||||
// DC_COMPLEX:
|
||||
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
||||
CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum),
|
||||
(PVOID) &RectEnum);
|
||||
PRect = RectEnum.arcl;
|
||||
for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++)
|
||||
{
|
||||
VGADDIIntersectRect(PRect,PRect,DestRect);
|
||||
ulWidth = PRect->right - PRect->left;
|
||||
|
||||
if (ulWidth <= MAX_SCAN_WIDTH)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
PRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
} else {
|
||||
// cut rect into slices MAX_SCAN_WIDTH wide
|
||||
ulRight = PRect->right; // save right edge
|
||||
PRect->right = PRect->left+MAX_SCAN_WIDTH;
|
||||
ulNumSlices = (ulWidth+MAX_SCAN_WIDTH-1) / MAX_SCAN_WIDTH;
|
||||
for (x=0; x<ulNumSlices-1; x++)
|
||||
{
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
PRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
PRect->left = PRect->right;
|
||||
PRect->right += MAX_SCAN_WIDTH;
|
||||
}
|
||||
PRect->right = ulRight;
|
||||
// Adjust the source point for clipping too
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
PRect, &TempPoint, pucDIB4ToVGAConvTables, DFB_TARGET);
|
||||
}
|
||||
}
|
||||
} while(EnumMore);
|
||||
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_1BPP:
|
||||
case BMF_8BPP:
|
||||
return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL,
|
||||
Clip, ColorTranslation,
|
||||
DestRect, SourcePoint,
|
||||
(POINTL *)NULL, (BRUSHOBJ *)NULL, (POINTL *)NULL,
|
||||
0x0000CCCC));
|
||||
}
|
||||
}
|
||||
|
||||
// Standard bitmap to screen
|
||||
if ((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE))
|
||||
{
|
||||
switch(Source->iBitmapFormat)
|
||||
{
|
||||
case BMF_4BPP:
|
||||
if (ColorTranslation == NULL)
|
||||
{
|
||||
pucDIB4ToVGAConvTables =
|
||||
((PDEVSURF) Dest->dhsurf)->ppdev->
|
||||
pucDIB4ToVGAConvTables;
|
||||
|
||||
// Make just enough of a fake DEVSURF for the source so that
|
||||
// the DIB to VGA code can work
|
||||
|
||||
TempDSurf.NextScan = Source->lDelta;
|
||||
TempDSurf.StartBmp = Source->pvScan0;
|
||||
|
||||
// Clip as needed
|
||||
|
||||
if ((Clip == NULL) || (Clip->iDComplexity == DC_TRIVIAL))
|
||||
{
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf, DestRect,
|
||||
SourcePoint, pucDIB4ToVGAConvTables, VGA_TARGET);
|
||||
|
||||
} else if (Clip->iDComplexity == DC_RECT)
|
||||
{
|
||||
if (VGADDIIntersectRect(&TempRect, DestRect, &Clip->rclBounds))
|
||||
{
|
||||
TempPoint.x = SourcePoint->x + TempRect.left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + TempRect.top - DestRect->top;
|
||||
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf, &TempDSurf,
|
||||
&TempRect, &TempPoint, pucDIB4ToVGAConvTables, VGA_TARGET);
|
||||
}
|
||||
return(TRUE);
|
||||
|
||||
} else {
|
||||
// DC_COMPLEX:
|
||||
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
||||
CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG)sizeof(RectEnum), (PVOID)&RectEnum);
|
||||
PRect = RectEnum.arcl;
|
||||
for (ircl = 0; ircl < RectEnum.c; ircl++, PRect++)
|
||||
{
|
||||
VGADDIIntersectRect(PRect,PRect,DestRect);
|
||||
|
||||
TempPoint.x = SourcePoint->x + PRect->left - DestRect->left;
|
||||
TempPoint.y = SourcePoint->y + PRect->top - DestRect->top;
|
||||
|
||||
DIB2VGA((PDEVSURF) Dest->dhsurf,
|
||||
&TempDSurf, PRect, &TempPoint,
|
||||
pucDIB4ToVGAConvTables, VGA_TARGET);
|
||||
}
|
||||
} while(EnumMore);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case BMF_1BPP:
|
||||
case BMF_8BPP:
|
||||
return(VGADDIBitBlt(Dest, Source, (SURFOBJ *)NULL,
|
||||
Clip, ColorTranslation,
|
||||
DestRect, SourcePoint,
|
||||
(POINTL *)NULL, (BRUSHOBJ *)NULL, (POINTL *)NULL,
|
||||
0x0000CCCC));
|
||||
|
||||
case BMF_8RLE:
|
||||
case BMF_4RLE:
|
||||
// return(RleBlt(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint));
|
||||
|
||||
}
|
||||
}
|
||||
// Screen to standard bitmap
|
||||
if ((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP))
|
||||
{
|
||||
if (Dest->iBitmapFormat == BMF_4BPP)
|
||||
{
|
||||
// pdsurf = (PDEVSURF) Source->dhsurf;
|
||||
|
||||
// Get the data for the destination DIB
|
||||
lDelta = Dest->lDelta;
|
||||
pjDstScan0 = (PBYTE) Dest->pvScan0;
|
||||
|
||||
// Setup for any color translation which may be needed !!! Is any needed at all?
|
||||
if (ColorTranslation == NULL)
|
||||
{
|
||||
pulXlate = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ColorTranslation->flXlate & XO_TABLE)
|
||||
{
|
||||
pulXlate = ColorTranslation->pulXlate;
|
||||
} else {
|
||||
pulXlate = (PULONG) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (Clip != (CLIPOBJ *) NULL)
|
||||
{
|
||||
switch(Clip->iDComplexity)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
EnumMore = FALSE;
|
||||
cben.c = 1;
|
||||
cben.arcl[0] = *DestRect;
|
||||
break;
|
||||
|
||||
case DC_RECT:
|
||||
EnumMore = FALSE;
|
||||
cben.c = 1;
|
||||
cben.arcl[0] = Clip->rclBounds;
|
||||
break;
|
||||
|
||||
case DC_COMPLEX:
|
||||
EnumMore = TRUE;
|
||||
cben.c = 0;
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EnumMore = FALSE;
|
||||
cben.c = 1;
|
||||
cben.arcl[0] = *DestRect; // Use the target for clipping
|
||||
}
|
||||
|
||||
// Call the VGA conversion routine, adjusted for each rectangle
|
||||
|
||||
do
|
||||
{
|
||||
LONG xSrc;
|
||||
LONG ySrc;
|
||||
RECTL *PRect;
|
||||
|
||||
if (EnumMore)
|
||||
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(cben), (PVOID) &cben);
|
||||
|
||||
for (ircl = 0; ircl < cben.c; ircl++)
|
||||
{
|
||||
PRect = &cben.arcl[ircl];
|
||||
|
||||
xSrc = SourcePoint->x + PRect->left - DestRect->left;
|
||||
ySrc = SourcePoint->y + PRect->top - DestRect->top;
|
||||
|
||||
VGAtoGDI(Dest, Source, NULL, ColorTranslation, DestRect, SourcePoint);
|
||||
|
||||
/* VGA2DIB(pdsurf, xSrc, ySrc, pjDstScan0,
|
||||
PRect->left, PRect->top, PRect->right - PRect->left,
|
||||
PRect->bottom - PRect->top,
|
||||
lDelta, Dest->iBitmapFormat, pulXlate); */
|
||||
}
|
||||
} while (EnumMore);
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
// If unsupported
|
||||
return(SimCopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint));
|
||||
}
|
||||
|
||||
BOOL SimCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
||||
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
||||
PRECTL DestRect, PPOINTL SourcePoint)
|
||||
{
|
||||
HBITMAP hbmTmp;
|
||||
SURFOBJ *psoTmp;
|
||||
RECTL rclTmp;
|
||||
SIZEL sizlTmp;
|
||||
BOOL bReturn = FALSE;
|
||||
POINTL ptl00 = {0,0};
|
||||
|
||||
rclTmp.top = rclTmp.left = 0;
|
||||
rclTmp.right = sizlTmp.cx = DestRect->right - DestRect->left;
|
||||
rclTmp.bottom = sizlTmp.cy = DestRect->bottom - DestRect->top;
|
||||
|
||||
// Create bitmap in our compatible format
|
||||
hbmTmp = EngCreateBitmap(sizlTmp, sizlTmp.cx * 1, BMF_4BPP, 0, NULL); // FIXME: Replace *1 with *BPP?
|
||||
|
||||
if (hbmTmp)
|
||||
{
|
||||
if ((psoTmp = EngLockSurface((HSURF)hbmTmp)) != NULL)
|
||||
{
|
||||
if (((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE)) ||
|
||||
((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVBITMAP)))
|
||||
{
|
||||
// DIB to VGA or DIB to DFB
|
||||
if (EngCopyBits(psoTmp, Source, NULL, ColorTranslation, &rclTmp, SourcePoint))
|
||||
{
|
||||
bReturn = VGADDICopyBits(Dest, psoTmp, Clip, NULL, DestRect, &ptl00);
|
||||
}
|
||||
}
|
||||
else if (((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP)) ||
|
||||
((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_BITMAP)))
|
||||
{
|
||||
// VGA to DIB or DFB to DIB
|
||||
if (VGADDICopyBits(psoTmp, Source, NULL, NULL, &rclTmp, SourcePoint))
|
||||
{
|
||||
bReturn = EngCopyBits(Dest, psoTmp, Clip, ColorTranslation, DestRect, &ptl00);
|
||||
}
|
||||
}
|
||||
else if (((Source->iType == STYPE_DEVICE) || (Source->iType == STYPE_DEVBITMAP)) &&
|
||||
((Dest->iType == STYPE_DEVICE) || (Dest->iType == STYPE_DEVBITMAP)))
|
||||
{
|
||||
// VGA or DFB to VGA or DFB
|
||||
if (VGADDICopyBits(psoTmp, Source, NULL, NULL, &rclTmp, SourcePoint))
|
||||
{
|
||||
bReturn = VGADDICopyBits(Dest, psoTmp, Clip, ColorTranslation, DestRect, &ptl00);
|
||||
}
|
||||
}
|
||||
|
||||
EngUnlockSurface(psoTmp);
|
||||
}
|
||||
|
||||
EngDeleteSurface((HSURF)hbmTmp);
|
||||
}
|
||||
|
||||
return(bReturn);
|
||||
}
|
|
@ -206,3 +206,7 @@ BOOL InitVGA(PPDEV ppdev, BOOL bFirst); // screen.c: initialize VGA mode
|
|||
#define DRIVER_OFFSCREEN_REFRESHED 0x04L // if not set, don't use offscreen memory
|
||||
#define PLANAR_PELS_PER_CPU_ADDRESS 8
|
||||
#define PACKED_PELS_PER_CPU_ADDRESS 2
|
||||
|
||||
BOOL VGAtoGDI(
|
||||
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
|
||||
RECTL *DestRect, POINTL *SourcePoint);
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddvid.h>
|
||||
|
||||
#include <ddk/winddi.h>
|
||||
#include "vgavideo.h"
|
||||
|
||||
#include <internal/i386/io.h>
|
||||
|
||||
INT abs(INT nm)
|
||||
{
|
||||
if(nm<0)
|
||||
{
|
||||
return nm * -1;
|
||||
} else
|
||||
{
|
||||
return nm;
|
||||
}
|
||||
}
|
||||
|
||||
div_t div(int num, int denom)
|
||||
{
|
||||
div_t r;
|
||||
|
@ -31,6 +42,40 @@ int mod(int num, int denom)
|
|||
return dvt.rem;
|
||||
}
|
||||
|
||||
BYTE bytesPerPixel(ULONG Format)
|
||||
{
|
||||
// This function is taken from /subsys/win32k/eng/surface.c
|
||||
// FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
|
||||
// pixel size if < 1 byte we expand it to 1 byte for simplicities sake
|
||||
|
||||
if(Format==BMF_1BPP)
|
||||
{
|
||||
return 1;
|
||||
} else
|
||||
if((Format==BMF_4BPP) || (Format==BMF_4RLE))
|
||||
{
|
||||
return 1;
|
||||
} else
|
||||
if((Format==BMF_8BPP) || (Format==BMF_8RLE))
|
||||
{
|
||||
return 1;
|
||||
} else
|
||||
if(Format==BMF_16BPP)
|
||||
{
|
||||
return 2;
|
||||
} else
|
||||
if(Format==BMF_24BPP)
|
||||
{
|
||||
return 3;
|
||||
} else
|
||||
if(Format==BMF_32BPP)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID vgaPreCalc()
|
||||
{
|
||||
ULONG j;
|
||||
|
@ -84,10 +129,10 @@ VOID vgaPreCalc()
|
|||
}
|
||||
}
|
||||
|
||||
void vgaPutPixel(int x, int y, unsigned char c)
|
||||
VOID vgaPutPixel(INT x, INT y, UCHAR c)
|
||||
{
|
||||
unsigned offset;
|
||||
unsigned char a;
|
||||
ULONG offset;
|
||||
UCHAR a;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
|
@ -98,9 +143,9 @@ void vgaPutPixel(int x, int y, unsigned char c)
|
|||
WRITE_REGISTER_UCHAR(vidmem + offset, c);
|
||||
}
|
||||
|
||||
void vgaPutByte(int x, int y, unsigned char c)
|
||||
VOID vgaPutByte(INT x, INT y, UCHAR c)
|
||||
{
|
||||
unsigned offset;
|
||||
ULONG offset;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
|
@ -111,30 +156,29 @@ void vgaPutByte(int x, int y, unsigned char c)
|
|||
WRITE_REGISTER_UCHAR(vidmem + offset, c);
|
||||
}
|
||||
|
||||
void vgaGetByte(unsigned offset,
|
||||
unsigned char *b, unsigned char *g,
|
||||
unsigned char *r, unsigned char *i)
|
||||
VOID vgaGetByte(ULONG offset,
|
||||
UCHAR *b, UCHAR *g,
|
||||
UCHAR *r, UCHAR *i)
|
||||
{
|
||||
// fixme: use READ_REGISTER_UCHAR
|
||||
|
||||
WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0304);
|
||||
*i = vidmem[offset];
|
||||
*i = READ_REGISTER_UCHAR(vidmem + offset);
|
||||
WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0204);
|
||||
*r = vidmem[offset];
|
||||
*r = READ_REGISTER_UCHAR(vidmem + offset);
|
||||
WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0104);
|
||||
*g = vidmem[offset];
|
||||
*g = READ_REGISTER_UCHAR(vidmem + offset);
|
||||
WRITE_PORT_USHORT((PUSHORT)0x03ce, 0x0004);
|
||||
*b = vidmem[offset];
|
||||
*b = READ_REGISTER_UCHAR(vidmem + offset);
|
||||
}
|
||||
|
||||
int vgaGetPixel(int x, int y)
|
||||
INT vgaGetPixel(INT x, INT y)
|
||||
{
|
||||
unsigned char mask, b, g, r, i;
|
||||
unsigned offset;
|
||||
UCHAR mask, b, g, r, i;
|
||||
ULONG offset;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
mask=maskbit[x];
|
||||
vgaGetByte(offset, &b, &g, &r, &i);
|
||||
|
||||
mask=maskbit[x];
|
||||
b=b&mask;
|
||||
g=g&mask;
|
||||
r=r&mask;
|
||||
|
@ -149,12 +193,12 @@ int vgaGetPixel(int x, int y)
|
|||
return(b+2*g+4*r+8*i);
|
||||
}
|
||||
|
||||
BOOL vgaHLine(int x, int y, int len, unsigned char c)
|
||||
BOOL vgaHLine(INT x, INT y, INT len, UCHAR c)
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int pre1, i;
|
||||
unsigned int orgpre1, orgx, midpre1;
|
||||
unsigned long leftpixs, midpixs, rightpixs, temp;
|
||||
UCHAR a;
|
||||
ULONG pre1, i;
|
||||
ULONG orgpre1, orgx, midpre1;
|
||||
ULONG long leftpixs, midpixs, rightpixs, temp;
|
||||
|
||||
orgx=x;
|
||||
|
||||
|
@ -244,10 +288,10 @@ BOOL vgaHLine(int x, int y, int len, unsigned char c)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL vgaVLine(int x, int y, int len, unsigned char c)
|
||||
BOOL vgaVLine(INT x, INT y, INT len, UCHAR c)
|
||||
{
|
||||
unsigned offset, i;
|
||||
unsigned char a;
|
||||
ULONG offset, i;
|
||||
UCHAR a;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
|
@ -265,3 +309,25 @@ BOOL vgaVLine(int x, int y, int len, unsigned char c)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const RECTL rclEmpty = { 0, 0, 0, 0 };
|
||||
|
||||
BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -28,3 +28,13 @@ typedef struct _VideoMode {
|
|||
} VideoMode;
|
||||
|
||||
VOID vgaPreCalc();
|
||||
VOID vgaPutPixel(INT x, INT y, UCHAR c);
|
||||
VOID vgaPutByte(INT x, INT y, UCHAR c);
|
||||
VOID vgaGetByte(ULONG offset,
|
||||
UCHAR *b, UCHAR *g,
|
||||
UCHAR *r, UCHAR *i);
|
||||
INT vgaGetPixel(INT x, INT y);
|
||||
BOOL vgaHLine(INT x, INT y, INT len, UCHAR c);
|
||||
BOOL vgaVLine(INT x, INT y, INT len, UCHAR c);
|
||||
INT abs(INT nm);
|
||||
BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2);
|
||||
|
|
|
@ -1035,6 +1035,8 @@ DWORD APIENTRY EngDeviceIoControl(
|
|||
DWORD nOutBufferSize,
|
||||
DWORD *lpBytesReturned);
|
||||
|
||||
VOID STDCALL EngFreeMem(PVOID Mem);
|
||||
|
||||
/*
|
||||
EngDeleteClip
|
||||
EngDeleteDriverObj
|
||||
|
@ -1049,7 +1051,6 @@ EngEraseSurface
|
|||
EngFillPath
|
||||
EngFindImageProcAddress
|
||||
EngFindResource
|
||||
EngFreeMem
|
||||
EngFreeModule
|
||||
EngFreeUserMem
|
||||
EngGetCurrentCodePage
|
||||
|
|
|
@ -15,22 +15,59 @@
|
|||
VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||
PRECTL DestRect, POINTL *SourcePoint,
|
||||
ULONG Delta)
|
||||
ULONG Delta, XLATEOBJ *ColorTranslation)
|
||||
{
|
||||
ULONG dy, leftOfSource, leftOfDest, Width;
|
||||
ULONG dy, leftOfSource, leftOfDest, Width, SourceBPP, DestBPP, RGBulong = 0, idxColor, i, TrivialCopy = 0;
|
||||
BYTE *SourcePos, *SourceInitial, *DestPos, *DestInitial;
|
||||
|
||||
// FIXME: Get ColorTranslation passed here and do something with it
|
||||
|
||||
if(ColorTranslation == NULL)
|
||||
{
|
||||
TrivialCopy = 1;
|
||||
} else if(ColorTranslation->flXlate & XO_TRIVIAL)
|
||||
{
|
||||
TrivialCopy = 1;
|
||||
}
|
||||
|
||||
leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
|
||||
leftOfDest = DestRect->left * DestGDI->BytesPerPixel;
|
||||
Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
|
||||
|
||||
if(TrivialCopy == 1)
|
||||
{
|
||||
for(dy=DestRect->top; dy<DestRect->bottom; dy++)
|
||||
{
|
||||
memcpy(DestSurf->pvBits+Delta*dy+leftOfDest,
|
||||
SourceSurf->pvBits+Delta*dy+leftOfSource,
|
||||
Width);
|
||||
}
|
||||
} else
|
||||
if(ColorTranslation->flXlate & XO_TABLE)
|
||||
{
|
||||
SourceBPP = bytesPerPixel(SourceSurf->iBitmapFormat);
|
||||
DestBPP = bytesPerPixel(DestSurf->iBitmapFormat);
|
||||
|
||||
SourcePos = SourceSurf->pvBits +
|
||||
(SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP);
|
||||
SourceInitial = SourcePos;
|
||||
|
||||
DestPos = DestSurf->pvBits +
|
||||
((DestRect->bottom - DestRect->top) * DestSurf->lDelta) + (DestRect->left * DestBPP);
|
||||
DestInitial = DestPos;
|
||||
|
||||
for(i=DestRect->left; i<DestRect->right; i++)
|
||||
{
|
||||
memcpy(&RGBulong, SourcePos, SourceBPP);
|
||||
idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong);
|
||||
memcpy(DestPos, &idxColor, DestBPP);
|
||||
|
||||
SourcePos+=SourceBPP;
|
||||
DestPos+=DestBPP;
|
||||
}
|
||||
SourcePos = SourceInitial + SourceSurf->lDelta;
|
||||
DestPos = DestInitial + DestSurf->lDelta;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
||||
|
@ -70,7 +107,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
|||
// Source surface is device managed
|
||||
if(Source->iType!=STYPE_BITMAP)
|
||||
{
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
|
||||
if (SourceGDI->CopyBits!=NULL)
|
||||
{
|
||||
|
@ -93,16 +130,19 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
|||
clippingType = Clip->iDComplexity;
|
||||
}
|
||||
|
||||
// We don't handle color translation just yet
|
||||
|
||||
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL))
|
||||
// We only handle XO_TABLE translations at the momement
|
||||
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
|
||||
(ColorTranslation->flXlate & XO_TABLE))
|
||||
{
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
|
||||
switch(clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
CopyBitsCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
DestRect, SourcePoint, Source->lDelta);
|
||||
DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
|
@ -117,7 +157,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
|||
|
||||
CopyBitsCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
&rclTmp, &ptlTmp, Source->lDelta);
|
||||
&rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
|
@ -145,7 +185,7 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
|||
|
||||
CopyBitsCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
prcl, &ptlTmp, Source->lDelta);
|
||||
prcl, &ptlTmp, Source->lDelta, ColorTranslation);
|
||||
|
||||
prcl++;
|
||||
|
||||
|
|
|
@ -191,9 +191,7 @@ BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
|
|||
if(Hooks & HOOK_STROKEPATH) SurfGDI->StrokePath = Dc->DriverFunctions.StrokePath;
|
||||
if(Hooks & HOOK_FILLPATH) SurfGDI->FillPath = Dc->DriverFunctions.FillPath;
|
||||
if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath;
|
||||
if(Hooks & HOOK_LINETO) { SurfGDI->LineTo = Dc->DriverFunctions.LineTo;
|
||||
DbgPrint("associating LineTo is now %08x\n", SurfGDI->LineTo);
|
||||
}
|
||||
if(Hooks & HOOK_LINETO) SurfGDI->LineTo = Dc->DriverFunctions.LineTo;
|
||||
if(Hooks & HOOK_COPYBITS) SurfGDI->CopyBits = Dc->DriverFunctions.CopyBits;
|
||||
if(Hooks & HOOK_SYNCHRONIZE) SurfGDI->Synchronize = Dc->DriverFunctions.Synchronize;
|
||||
if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
|
||||
|
@ -218,7 +216,8 @@ BOOL EngDeleteSurface(HSURF Surface)
|
|||
|
||||
SURFOBJ *EngLockSurface(HSURF Surface)
|
||||
{
|
||||
// FIXME: Do we need to allocate new memory for this user object??
|
||||
// FIXME: Do we need to allocate new memory for this user object?? Since there's an unlock.. it appears to be so
|
||||
// probably because win32k is supposed to do some kind of wierd handle\object thing that we don't
|
||||
|
||||
return AccessUserObject(Surface);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ STUB(EngEnumForms)
|
|||
STUB(EngFillPath)
|
||||
STUB(EngFindImageProcAddress)
|
||||
STUB(EngFindResource)
|
||||
STUB(EngFreeMem)
|
||||
STUB(EngFreeModule)
|
||||
STUB(EngFreeUserMem)
|
||||
STUB(EngGetCurrentCodePage)
|
||||
|
|
Loading…
Reference in a new issue