Implemented DrvPaint and DrvBitBlt

Added tests for new routines
Minor fixes

svn path=/trunk/; revision=1102
This commit is contained in:
Jason Filby 2000-04-03 19:55:33 +00:00
parent 3b0f32720d
commit eb1f2f9bd1
8 changed files with 600 additions and 12 deletions

View file

@ -1,9 +1,9 @@
/*
* entry.c
*
* $Revision: 1.3 $
* $Revision: 1.4 $
* $Author: jfilby $
* $Date: 2000/04/01 12:31:28 $
* $Date: 2000/04/03 19:55:32 $
*
*/
@ -37,6 +37,13 @@ ULONG VGADDIGetModes(IN HANDLE Driver,
BOOL VGADDILineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
LONG x1, LONG y1, LONG x2, LONG y2,
RECTL *RectBounds, MIX mix);
BOOL VGADDIPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
IN MIX Mix);
BOOL VGADDIBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask,
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4);
DRVFN FuncList[] =
{
@ -49,11 +56,12 @@ DRVFN FuncList[] =
{INDEX_DrvEnableSurface, (PFN) VGADDIEnableSurface},
{INDEX_DrvGetModes, (PFN) VGADDIGetModes},
{INDEX_DrvLineTo, (PFN) VGADDILineTo},
{INDEX_DrvPaint, (PFN) VGADDIPaint},
{INDEX_DrvBitBlt, (PFN) VGADDIBitBlt},
#if 0
/* Optional Display driver functions */
{INDEX_, (PFN) },
{INDEX_DrvBitBlt, (PFN) VGADDIBitBlt},
{INDEX_DrvCopyBits, (PFN) VGADDICopyBits},
{INDEX_DescribePixelFormat, (PFN) VGADDIDescribePixelFormat},
{INDEX_DrvDitherColor, (PFN) VGADDIDitherColor},
@ -61,7 +69,6 @@ DRVFN FuncList[] =
{INDEX_DrvGetTrueTypeFile, (PFN) VGADDIGetTrueTypeFile},
{INDEX_DrvLoadFontFile, (PFN) VGADDILoadFontFile},
{INDEX_DrvMovePointer, (PFN) VGADDIMovePointer},
{INDEX_DrvPaint, (PFN) VGADDIPaint}
{INDEX_DrvQueryFont, (PFN) VGADDIQueryFont},
{INDEX_DrvQueryFontCaps, (PFN) VGADDIQueryFontCaps},
{INDEX_DrvQueryFontData, (PFN) VGADDIQueryFontData},

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.3 2000/04/01 12:31:28 jfilby Exp $
# $Id: makefile,v 1.4 2000/04/03 19:55: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 vgavideo/vgavideo.o
OTHER_OBJECTS = objects/screen.o objects/lineto.o objects/paint.o objects/bitblt.o vgavideo/vgavideo.o
RESOURCE_OBJECTS = $(TARGET).coff
OBJECTS = $(MAIN_OBJECTS) $(OTHER_OBJECTS) $(RESOURCE_OBJECTS)

View file

@ -0,0 +1,225 @@
#include "..\vgaddi.h"
#include "..\vgavideo\vgavideo.h"
#include "brush.h"
#include "bitblt.h"
// FIXME:
// RGBtoULONG (eng/xlate.c) will be faster than RtlCopyMemory?
// Note: All of our BitBlt ops expect to be working with 4BPP data
typedef BOOL (*PFN_VGABlt)(SURFOBJ *, SURFOBJ *, SURFOBJ *, XLATEOBJ *,
RECTL *, POINTL *);
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;
BYTE *GDIpos, *initial;
BPP = bytesPerPixel(Source->iBitmapFormat);
GDIpos = Source->pvBits +
SourcePoint->y * Source->lDelta + SourcePoint->x;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
alterx = abs(SourcePoint->x - DestRect->left);
altery = abs(SourcePoint->y - DestRect->top);
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
{
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
{
RtlCopyMemory(&RGBulong, GDIpos, BPP);
idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong);
vgaPutPixel(i+alterx, j+altery, idxColor);
GDIpos+=BPP;
}
GDIpos = initial + Source->lDelta;
}
}
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;
BPP = bytesPerPixel(Dest->iBitmapFormat);
GDIpos = Dest->pvBits +
DestRect->top * Dest->lDelta + DestRect->left;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
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,
RECTL *DestRect, POINTL *SourcePoint)
{
// Do DFBs need color translation??
}
BOOL VGAtoDFB(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
// Do DFBs need color translation??
}
BOOL VGAtoVGA(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
// FIXME: Use fast blts instead of get and putpixels
int i, j, dx, dy, alterx, altery, BltDirection;
// Calculate deltas
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
alterx = abs(SourcePoint->x - DestRect->left);
altery = abs(SourcePoint->y - DestRect->top);
// Determine bltting direction
// FIXME: should we perhaps make this an EngXxx function? Determining
// direction is probably used whenever the surfaces are the same (not
// just VGA screen)
if (SourcePoint->y >= DestRect->top)
{
if (SourcePoint->x >= DestRect->left)
{
BltDirection = CD_RIGHTDOWN;
}
else
{
BltDirection = CD_LEFTDOWN;
}
}
else
{
if (SourcePoint->x >= DestRect->left)
{
BltDirection = CD_RIGHTUP;
}
else
{
BltDirection = CD_LEFTUP;
}
}
// Do the VGA to VGA BitBlt
// FIXME: Right now we're only doing CN_LEFTDOWN and we're using slow
// get and put pixel routines
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
{
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
{
vgaPutPixel(i+alterx, j+altery, vgaGetPixel(i, j));
}
}
return TRUE;
}
BOOL VGADDIBitBlt(SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask,
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
{
RECT_ENUM RectEnum;
BOOL EnumMore;
PFN_VGABlt BltOperation;
// Determine the bltbit operation
if((Source->iType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE))
{
BltOperation = GDItoVGA;
} else
if((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP))
{
BltOperation = VGAtoGDI;
} else
if((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVICE))
{
BltOperation = VGAtoVGA;
} else
if((Source->iType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVICE))
{
BltOperation = DFBtoVGA;
} else
if((Source->iType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVBITMAP))
{
BltOperation = VGAtoDFB;
} else
{
// Cannot handle given surfaces for VGA BitBlt
return FALSE;
}
// Perform the necessary operatings according to the clipping
if(Clip == NULL)
{
BltOperation(Dest, Source, Mask, ColorTranslation, DestRect,
SourcePoint);
} else
{
switch(Clip->iMode) {
case TC_RECTANGLES:
if (Clip->iDComplexity == DC_RECT)
{
// FIXME: Intersect clip rectangle
BltOperation(Dest, Source, ColorTranslation, Mask,
DestRect, SourcePoint);
} else {
// Enumerate all the rectangles and draw them
/* CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY,
ENUM_RECT_LIMIT);
do {
EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID) &RectEnum);
// FIXME: Calc new source point (diff between new & old destrects?)
VGADDIFillSolid(Dest, Srouce, Mask,
&RectEnum.arcl[0], NewSourcePoint);
} while (EnumMore); */
}
}
}
return TRUE;
}

View file

@ -0,0 +1,22 @@
/// Define the A vector polynomial bits
// Each bit corresponds to one of the terms in the polynomial
//
// Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP
// 0 d s p ds dp sp dsp
#define AVEC_NOT 0x01
#define AVEC_D 0x02
#define AVEC_S 0x04
#define AVEC_P 0x08
#define AVEC_DS 0x10
#define AVEC_DP 0x20
#define AVEC_SP 0x40
#define AVEC_DSP 0x80
#define AVEC_NEED_SOURCE (AVEC_S | AVEC_DS | AVEC_SP | AVEC_DSP)
#define AVEC_NEED_PATTERN (AVEC_P | AVEC_DP | AVEC_SP | AVEC_DSP)
#define BB_TARGET_SCREEN 0x0001
#define BB_TARGET_ONLY 0x0002
#define BB_SOURCE_COPY 0x0004
#define BB_PATTERN_COPY 0x0008

View file

@ -0,0 +1,58 @@
typedef struct _BRUSHINST
{
// We need to removed ajC0-3 when color pattern code is complete!!!
//
BYTE ajC0[8]; // Color bits for plane 0
BYTE ajC1[8]; // Color bits for plane 1
BYTE ajC2[8]; // Color bits for plane 2
BYTE ajC3[8]; // Color bits for plane 3
BYTE ajPattern[32]; // Color bits for the mask
USHORT usStyle; // Brush style
BYTE fjAccel; // Accelerator flags
BYTE jFgColor; // Current foreground color
BYTE jBkColor; // Current background color
BYTE RealWidth; //
BYTE YShiftValue; //
BYTE jOldBrushRealized; //
DWORD Width; // Width of brush
DWORD Height;
BYTE *pPattern; //Pointer to realized mono pattern
} BRUSHINST;
#define BRI_SOLID 0
#define BRI_HOLLOW 1
#define BRI_HATCHED 2
#define BRI_PATTERN 3
#define BRI_MONO_PATTERN 4
#define BRI_COLOR_PATTERN 5
// Definitions for the pcol_C3 byte of the physical color
//
// Some of these definitions have limitations as to when they
// are valid. They are as follows:
//
// C0_BIT color device, phys color, solid brushes if SOLID_COLOR
// C1_BIT color device, phys color, solid brushes if SOLID_COLOR
// C2_BIT color device, phys color, solid brushes if SOLID_COLOR
// C3_BIT color device, phys color, solid brushes if SOLID_COLOR
// MONO_BIT mono device, phys color
// ONES_OR_ZEROS color device, phys color, solid brushes if SOLID_COLOR
// GREY_SCALE color device, dithered solid and hatched brushes
// SOLID_BRUSH color device, solid brush qualifier
//
// There may be brushes where the accelerators could have been set,
// but wasn't. That's life.
#define C0_BIT 0x01 // C0 color
#define C1_BIT 0x02 // C1 color
#define C2_BIT 0x04 // C2 color
#define C3_BIT 0x08 // C3 color
#define COLOR_BITS 0x0f // All the color bits
#define MONO_BIT 0x10 // Monochrome bit
#define ONES_OR_ZEROS 0x20 // Color is really all 1's or all 0's
#define GREY_SCALE 0x40 // Indicates a real grey scale brush
#define SOLID_BRUSH 0x80 // Indicates a solid color brush
#define PTRI_INVERT 0x0001
#define PTRI_ANIMATE 0x0002

View file

@ -0,0 +1,217 @@
#include "..\vgaddi.h"
#include "..\vgavideo\vgavideo.h"
#include "brush.h"
BOOL VGADDIFillSolid(SURFOBJ *Surface, RECTL Dimensions, ULONG iColor)
{
unsigned char a, b, mask;
unsigned int pre1, i, j, newx;
unsigned int orgpre1, orgx, midpre1;
unsigned long leftpixs, midpixs, rightpixs, temp, len;
long calc;
orgx=Dimensions.left;
len=Dimensions.right - Dimensions.left;
Dimensions.bottom++;
if(len<8)
{
for (i=Dimensions.left; i<Dimensions.left+len; i++)
vgaPutPixel(i, Dimensions.top, iColor);
} else {
leftpixs=Dimensions.left;
while(leftpixs>8) leftpixs-=8;
temp = len;
midpixs = 0;
while(temp>7)
{
temp-=8;
midpixs++;
}
if((temp>=0) && (midpixs>0)) midpixs--;
pre1=xconv[Dimensions.left]+y80[Dimensions.top];
orgpre1=pre1;
// Left
if(leftpixs==8) {
// Left edge should be an entire middle bar
Dimensions.left=orgx;
leftpixs=0;
}
else if(leftpixs>0)
{
WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // Set
WRITE_PORT_UCHAR((PUCHAR)0x3cf,startmasks[leftpixs]); // the MASK
for(j=Dimensions.top; j<Dimensions.bottom; j++)
{
a = READ_REGISTER_UCHAR(vidmem + pre1);
WRITE_REGISTER_UCHAR(vidmem + pre1, iColor);
pre1+=80;
}
// Middle
Dimensions.left=orgx+(8-leftpixs)+leftpixs;
} else {
// leftpixs == 0
midpixs+=1;
}
if(midpixs>0)
{
midpre1=xconv[Dimensions.left]+y80[Dimensions.top];
// Set mask to all pixels in byte
WRITE_PORT_UCHAR((PUCHAR)0x3ce, 0x08);
WRITE_PORT_UCHAR((PUCHAR)0x3cf, 0xff);
for(j=Dimensions.top; j<Dimensions.bottom; j++)
{
memset(vidmem+midpre1, iColor, midpixs);
midpre1+=80;
}
}
rightpixs = len - ((midpixs*8) + leftpixs);
if((rightpixs>0))
{
Dimensions.left=(orgx+len)-rightpixs;
// Go backwards till we reach the 8-byte boundary
while(mod(Dimensions.left, 8)!=0) { Dimensions.left--; rightpixs++; }
while(rightpixs>7)
{
// This is a BAD case as this should have been a midpixs
for(j=Dimensions.top; j<Dimensions.bottom; j++)
vgaPutByte(Dimensions.left, j, iColor);
rightpixs-=8;
Dimensions.left+=8;
}
pre1=xconv[Dimensions.left]+y80[Dimensions.top];
WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // Set
WRITE_PORT_UCHAR((PUCHAR)0x3cf,endmasks[rightpixs]); // the MASK
for(j=Dimensions.top; j<Dimensions.bottom; j++)
{
a = READ_REGISTER_UCHAR(vidmem + pre1);
WRITE_REGISTER_UCHAR(vidmem + pre1, iColor);
pre1+=80;
}
}
}
return TRUE;
}
BOOL VGADDIPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
BRUSHINST *BrushInst, POINTL *BrushPoint)
{
RECT_ENUM RectEnum;
BOOL EnumMore;
switch(ClipRegion->iMode) {
case TC_RECTANGLES:
/* Rectangular clipping can be handled without enumeration.
Note that trivial clipping is not possible, since the clipping
region defines the area to fill */
if (ClipRegion->iDComplexity == DC_RECT)
{
VGADDIFillSolid(Surface, ClipRegion->rclBounds, iColor);
} else {
/* Enumerate all the rectangles and draw them */
/* CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY,
ENUM_RECT_LIMIT);
do {
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
VGADDIFillSolid(Surface, &RectEnum.arcl[0], iColor);
} while (EnumMore); */
}
return(TRUE);
default:
return(FALSE);
}
}
BOOL VGADDIPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
IN MIX Mix)
{
ULONG iSolidColor;
iSolidColor = Brush->iSolidColor; // FIXME: Realizations and the like
// If the foreground and background Mixes are the same,
// (LATER or if there's no brush mask)
// then see if we can use the solid brush accelerators
// FIXME: Put in the mix switch below
// Brush color parameter doesn't matter for these rops
return(VGADDIPaintRgn(Surface, ClipRegion, iSolidColor, Mix, NULL, BrushOrigin));
if ((Mix & 0xFF) == ((Mix >> 8) & 0xFF))
{
switch (Mix & 0xFF)
{
case 0:
break;
// FIXME: Implement all these millions of ROPs
// For now we don't support brushes -- everything is solid
case R2_MASKNOTPEN:
case R2_NOTCOPYPEN:
case R2_XORPEN:
case R2_MASKPEN:
case R2_NOTXORPEN:
case R2_MERGENOTPEN:
case R2_COPYPEN:
case R2_MERGEPEN:
case R2_NOTMERGEPEN:
case R2_MASKPENNOT:
case R2_NOTMASKPEN:
case R2_MERGEPENNOT:
// Rops that are implicit solid colors
case R2_NOT:
case R2_WHITE:
case R2_BLACK:
// FIXME: The Paint region belongs HERE
case R2_NOP:
return(TRUE);
default:
break;
}
}
doBitBlt:
// If VGADDIPaint can't do it, VGADDIBitBlt can.. or it might just loop back
// here and we have a nice infinite loop
/* return( VGADDIBitBlt(Surface, (SURFOBJ *)NULL, (SURFOBJ *)NULL, ClipRegion,
(XLATEOBJ *)NULL, &ClipRegion->rclBounds,
NULL, (POINTL *)NULL, Brush, BrushOrigin,
NULL) ); UNIMPLEMENTED */
}

View file

@ -51,6 +51,8 @@ CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
ClipObj->iFComplexity = FC_COMPLEX;
}
}
return ClipObj;
}
VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)

View file

@ -1,4 +1,4 @@
/* $Id: dc.c,v 1.14 2000/04/01 12:31:29 jfilby Exp $
/* $Id: dc.c,v 1.15 2000/04/03 19:55:33 jfilby Exp $
*
* DC.C - Device context functions
*
@ -20,22 +20,79 @@
void TestEngXxx(PDC Dc)
{
BRUSHOBJ brushobj;
SURFOBJ *SurfObj;
BRUSHOBJ brushobj;
HBITMAP GDIbmp;
SURFOBJ *SurfObj, *GDIsurf;
XLATEOBJ *RGBtoVGA16, *VGA16toRGB;
RECTL DestBlt, myrect;
SIZEL GDISize;
CLIPOBJ *clipobj;
POINTL SourcePnt;
INT i;
DbgPrint("testing.. ");
brushobj.iSolidColor = 1;
SurfObj = AccessUserObject(Dc->Surface);
/* Diagonals */
/* Create a GDI managed bitmap */
GDISize.cx = 100;
GDISize.cy = 100;
GDIbmp = EngCreateBitmap(GDISize, GDISize.cx * 3, BMF_24BPP, BMF_TOPDOWN,
NULL);
// Get GDI surface's object
GDIsurf = AccessUserObject(GDIbmp);
/* Create color translation Xlates */
// Create color translation for RGB to the VGA's 16 colors
RGBtoVGA16 = EngCreateXlate(PAL_INDEXED, PAL_RGB,
Dc->DevInfo.hpalDefault, NULL);
// Create color translation for RGB to the VGA's 16 colors
VGA16toRGB = EngCreateXlate(PAL_RGB, PAL_INDEXED,
NULL, Dc->DevInfo.hpalDefault);
/* Line Tests */
// Diagonals
EngLineTo(SurfObj, NULL, &brushobj, 0, 0, 639, 479, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 639, 0, 0, 479, NULL, NULL);
/* Border */
// Border
EngLineTo(SurfObj, NULL, &brushobj, 0, 0, 639, 0, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 639, 0, 639, 479, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 639, 479, 0, 479, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 0, 479, 0, 0, NULL, NULL);
/* Paint Tests */
// Colored blocks
for (i=0; i<16; i++)
{
myrect.left=10+i*20;
myrect.top=10;
myrect.right=30+i*20;
myrect.bottom=30;
clipobj = EngCreateClipRegion(1, &myrect, TC_RECTANGLES, NULL);
brushobj.iSolidColor = i;
EngPaint(SurfObj, clipobj, &brushobj, NULL, 0xFF);
EngDeleteClipRegion(clipobj);
}
/* BitBlt */
// Blt VGA to GDI
DestBlt.left=0; DestBlt.top=0; DestBlt.right=100, DestBlt.bottom=100;
SourcePnt.x=10; SourcePnt.y=10;
EngBitBlt(GDIsurf, SurfObj, NULL, NULL, VGA16toRGB, &DestBlt, &SourcePnt,
NULL, NULL, NULL, NULL);
// Blt to VGA again
DestBlt.left=300; DestBlt.top=300; DestBlt.right=400, DestBlt.bottom=400;
SourcePnt.x=0; SourcePnt.y=0;
EngBitBlt(SurfObj, GDIsurf, NULL, NULL, RGBtoVGA16, &DestBlt, &SourcePnt,
NULL, NULL, NULL, NULL);
}
/* FIXME: DCs should probably be thread safe */