mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Identation corrected, many fixes and minor improvements, initial DIB support
svn path=/trunk/; revision=1753
This commit is contained in:
parent
a934fd1c24
commit
14c634ca97
42 changed files with 4532 additions and 2967 deletions
17
reactos/subsys/win32k/dib/dib.h
Normal file
17
reactos/subsys/win32k/dib/dib.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
static unsigned char notmask[2] = { 0x0f, 0xf0 };
|
||||
static unsigned char altnotmask[2] = { 0xf0, 0x0f };
|
||||
|
||||
typedef VOID (*PFN_DIB_PutPixel)(SURFOBJ *, LONG, LONG, ULONG);
|
||||
typedef ULONG (*PFN_DIB_GetPixel)(SURFOBJ *, LONG, LONG);
|
||||
typedef VOID (*PFN_DIB_HLine) (SURFOBJ *, LONG, LONG, LONG, ULONG);
|
||||
typedef VOID (*PFN_DIB_VLine) (SURFOBJ *, LONG, LONG, LONG, ULONG);
|
||||
|
||||
VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, BYTE c);
|
||||
BYTE DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y);
|
||||
VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, BYTE c);
|
||||
VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, BYTE c);
|
||||
|
||||
VOID DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, RGBTRIPLE c);
|
||||
RGBTRIPLE DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y);
|
||||
VOID DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, RGBTRIPLE c);
|
||||
VOID DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, RGBTRIPLE c);
|
134
reactos/subsys/win32k/dib/dib24bpp.c
Normal file
134
reactos/subsys/win32k/dib/dib24bpp.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <win32k/bitmaps.h>
|
||||
#include <win32k/debug.h>
|
||||
#include <debug.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include "..\eng\objects.h"
|
||||
#include "dib.h"
|
||||
|
||||
VOID DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, RGBTRIPLE c)
|
||||
{
|
||||
PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
|
||||
PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x;
|
||||
|
||||
*addr = c;
|
||||
}
|
||||
|
||||
RGBTRIPLE DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
|
||||
{
|
||||
PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
|
||||
PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x;
|
||||
|
||||
return *addr;
|
||||
}
|
||||
|
||||
VOID DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, RGBTRIPLE c)
|
||||
{
|
||||
PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
|
||||
PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x1;
|
||||
LONG cx = x1;
|
||||
|
||||
while(cx <= x2) {
|
||||
*addr = c;
|
||||
++addr;
|
||||
++cx;
|
||||
}
|
||||
}
|
||||
|
||||
VOID DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, RGBTRIPLE c)
|
||||
{
|
||||
PBYTE byteaddr = SurfObj->pvBits + y1 * SurfObj->lDelta;
|
||||
PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x;
|
||||
ULONG lDelta = SurfObj->lDelta;
|
||||
|
||||
byteaddr = (PBYTE)addr;
|
||||
while(y1++ <= y2) {
|
||||
*addr = c;
|
||||
|
||||
byteaddr += lDelta;
|
||||
addr = (PRGBTRIPLE)byteaddr;
|
||||
}
|
||||
}
|
||||
|
||||
VOID DIB_24BPP_BltTo_24BPP(PSURFOBJ dstpsd, LONG dstx, LONG dsty, LONG w, LONG h,
|
||||
PSURFOBJ srcpsd, LONG srcx, LONG srcy)
|
||||
{
|
||||
PRGBTRIPLE dst;
|
||||
PRGBTRIPLE src;
|
||||
PBYTE bytedst;
|
||||
PBYTE bytesrc;
|
||||
int i;
|
||||
int dlDelta = dstpsd->lDelta;
|
||||
int slDelta = srcpsd->lDelta;
|
||||
|
||||
bytedst = (char *)dstpsd->pvBits + dsty * dlDelta;
|
||||
bytesrc = (char *)srcpsd->pvBits + srcy * slDelta;
|
||||
dst = (PRGBTRIPLE)bytedst + dstx;
|
||||
src = (PRGBTRIPLE)bytesrc + srcx;
|
||||
|
||||
while(--h >= 0) {
|
||||
PRGBTRIPLE d = dst;
|
||||
PRGBTRIPLE s = src;
|
||||
LONG dx = dstx;
|
||||
LONG sx = srcx;
|
||||
for(i=0; i<w; ++i) {
|
||||
*d = *s;
|
||||
++d;
|
||||
++s;
|
||||
}
|
||||
dst += dlDelta;
|
||||
src += slDelta;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN DIB_To_24BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||
PRECTL DestRect, POINTL *SourcePoint,
|
||||
ULONG Delta, XLATEOBJ *ColorTranslation)
|
||||
{
|
||||
ULONG i, j, sx, xColor, f1;
|
||||
PBYTE DestBits, SourceBits_24BPP, DestLine, SourceLine_24BPP;
|
||||
PRGBTRIPLE SPDestBits, SPSourceBits_24BPP, SPDestLine, SPSourceLine_24BPP; // specially for 24-to-24 blit
|
||||
PBYTE SourceBits_4BPP, SourceBits_8BPP, SourceLine_4BPP, SourceLine_8BPP;
|
||||
PWORD SourceBits_16BPP, SourceLine_16BPP;
|
||||
PDWORD SourceBits_32BPP, SourceLine_32BPP;
|
||||
|
||||
DestBits = DestSurf->pvBits + (DestRect->top * DestSurf->lDelta) + DestRect->left * 3;
|
||||
|
||||
switch(SourceGDI->BitsPerPixel)
|
||||
{
|
||||
case 4:
|
||||
SourceBits_4BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
|
||||
|
||||
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||
{
|
||||
SourceLine_4BPP = SourceBits_4BPP;
|
||||
DestLine = DestBits;
|
||||
sx = SourcePoint->x;
|
||||
f1 = sx & 1;
|
||||
|
||||
for (i=DestRect->left; i<DestRect->right; i++)
|
||||
{
|
||||
xColor = XLATEOBJ_iXlate(ColorTranslation,
|
||||
(*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1))));
|
||||
*DestLine++ = xColor & 0xff;
|
||||
*(PWORD)DestLine = xColor >> 8;
|
||||
DestLine += 2;
|
||||
if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
|
||||
sx++;
|
||||
}
|
||||
|
||||
SourceBits_4BPP += SourceSurf->lDelta;
|
||||
DestBits += DestSurf->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
129
reactos/subsys/win32k/dib/dib4bpp.c
Normal file
129
reactos/subsys/win32k/dib/dib4bpp.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <win32k/bitmaps.h>
|
||||
#include <win32k/debug.h>
|
||||
#include <debug.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include "..\eng\objects.h"
|
||||
#include "dib.h"
|
||||
|
||||
VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, BYTE c)
|
||||
{
|
||||
unsigned char *vp;
|
||||
unsigned char mask;
|
||||
PBYTE addr = SurfObj->pvBits;
|
||||
|
||||
addr += (x>>1) + y * SurfObj->lDelta;
|
||||
*addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2));
|
||||
}
|
||||
|
||||
BYTE DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
|
||||
{
|
||||
PBYTE addr = SurfObj->pvBits;
|
||||
|
||||
return (addr[(x>>1) + y * SurfObj->lDelta] >> ((1-(x&1))<<2) ) & 0x0f;
|
||||
}
|
||||
|
||||
VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, BYTE c)
|
||||
{
|
||||
PBYTE addr = SurfObj->pvBits + (x1>>1) + y * SurfObj->lDelta;
|
||||
LONG cx = x1;
|
||||
|
||||
while(cx <= x2) {
|
||||
*addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2));
|
||||
if((++x1 & 1) == 0)
|
||||
++addr;
|
||||
++cx;
|
||||
}
|
||||
}
|
||||
|
||||
VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, BYTE c)
|
||||
{
|
||||
PBYTE addr = SurfObj->pvBits;
|
||||
int lDelta = SurfObj->lDelta;
|
||||
|
||||
addr += (x>>1) + y1 * lDelta;
|
||||
while(y1++ <= y2) {
|
||||
*addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2));
|
||||
addr += lDelta;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||
PRECTL DestRect, POINTL *SourcePoint,
|
||||
ULONG Delta, XLATEOBJ *ColorTranslation)
|
||||
{
|
||||
ULONG i, j, sx, f1, f2, xColor;
|
||||
PBYTE SourceBits_24BPP, SourceLine_24BPP;
|
||||
PBYTE DestBits, DestLine, SourceBits_4BPP, SourceBits_8BPP, SourceLine_4BPP, SourceLine_8BPP;
|
||||
PWORD SourceBits_16BPP, SourceLine_16BPP;
|
||||
PDWORD SourceBits_32BPP, SourceLine_32BPP;
|
||||
|
||||
DestBits = DestSurf->pvBits + (DestRect->left>>1) + DestRect->top * DestSurf->lDelta;
|
||||
|
||||
switch(SourceGDI->BitsPerPixel)
|
||||
{
|
||||
case 4:
|
||||
SourceBits_4BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
|
||||
|
||||
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||
{
|
||||
SourceLine_4BPP = SourceBits_4BPP;
|
||||
DestLine = DestBits;
|
||||
sx = SourcePoint->x;
|
||||
f1 = sx & 1;
|
||||
f2 = DestRect->left & 1;
|
||||
|
||||
// FIXME: handle odd begin pixel
|
||||
|
||||
for (i=DestRect->left; i<DestRect->right; i++)
|
||||
{
|
||||
if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
|
||||
if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; *DestLine = *SourceLine_4BPP; }
|
||||
sx++;
|
||||
}
|
||||
|
||||
// FIXME: handle odd end pixel
|
||||
|
||||
SourceBits_4BPP += SourceSurf->lDelta;
|
||||
DestBits += DestSurf->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
SourceBits_24BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3;
|
||||
|
||||
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||
{
|
||||
SourceLine_24BPP = SourceBits_24BPP;
|
||||
DestLine = DestBits;
|
||||
sx = SourcePoint->x;
|
||||
f1 = sx & 1;
|
||||
f2 = DestRect->left & 1;
|
||||
|
||||
for (i=DestRect->left; i<DestRect->right; i++)
|
||||
{
|
||||
xColor = (*(SourceLine_24BPP + 2) << 0x10) +
|
||||
(*(SourceLine_24BPP + 1) << 0x08) +
|
||||
(*(SourceLine_24BPP));
|
||||
*DestLine = (*DestLine & notmask[i&1]) |
|
||||
((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(sx & 1)))));
|
||||
if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
|
||||
SourceLine_24BPP+=3;
|
||||
sx++;
|
||||
}
|
||||
|
||||
SourceBits_24BPP += SourceSurf->lDelta;
|
||||
DestBits += DestSurf->lDelta;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -15,212 +15,159 @@
|
|||
#include "enum.h"
|
||||
#include "objects.h"
|
||||
|
||||
VOID BitBltCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||
PRECTL DestRect, POINTL *SourcePoint,
|
||||
ULONG Delta)
|
||||
{
|
||||
ULONG dy, leftOfSource, leftOfDest, Width, CopyPos;
|
||||
|
||||
// FIXME: Get ColorTranslation passed here and do something with it
|
||||
|
||||
leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
|
||||
leftOfDest = DestRect->left * DestGDI->BytesPerPixel;
|
||||
Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
|
||||
CopyPos = leftOfDest;
|
||||
|
||||
for(dy=DestRect->top; dy<DestRect->bottom; dy++)
|
||||
{
|
||||
RtlCopyMemory(DestSurf->pvBits+CopyPos,
|
||||
SourceSurf->pvBits+CopyPos,
|
||||
Width);
|
||||
|
||||
CopyPos += Delta;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
|
||||
|
||||
{
|
||||
static const RECTL rclEmpty = { 0, 0, 0, 0 };
|
||||
static const RECTL rclEmpty = { 0, 0, 0, 0 };
|
||||
|
||||
prcDst->left = max(prcSrc1->left, prcSrc2->left);
|
||||
prcDst->right = min(prcSrc1->right, prcSrc2->right);
|
||||
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->left < prcDst->right)
|
||||
{
|
||||
prcDst->top = max(prcSrc1->top, prcSrc2->top);
|
||||
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
|
||||
|
||||
if (prcDst->top < prcDst->bottom)
|
||||
return(TRUE);
|
||||
}
|
||||
if (prcDst->top < prcDst->bottom) return(TRUE);
|
||||
}
|
||||
|
||||
*prcDst = rclEmpty;
|
||||
*prcDst = rclEmpty;
|
||||
|
||||
return(FALSE);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
||||
SURFOBJ *Mask, CLIPOBJ *ClipRegion,
|
||||
XLATEOBJ *ColorTranslation, RECTL *DestRect,
|
||||
POINTL *SourcePoint, POINTL *MaskRect,
|
||||
BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4)
|
||||
{
|
||||
BYTE clippingType;
|
||||
RECTL rclTmp;
|
||||
POINTL ptlTmp;
|
||||
RECT_ENUM RectEnum;
|
||||
BOOL EnumMore;
|
||||
SURFGDI *DestGDI, *SourceGDI;
|
||||
BOOLEAN canCopyBits;
|
||||
BYTE clippingType;
|
||||
RECTL rclTmp;
|
||||
POINTL ptlTmp;
|
||||
RECT_ENUM RectEnum;
|
||||
BOOL EnumMore;
|
||||
PSURFGDI DestGDI, SourceGDI;
|
||||
HSURF hTemp;
|
||||
PSURFOBJ TempSurf;
|
||||
BOOLEAN canCopyBits;
|
||||
POINTL TempPoint;
|
||||
RECTL TempRect;
|
||||
SIZEL TempSize;
|
||||
|
||||
// If we don't have to do anything special, we can punt to DrvCopyBits
|
||||
// if it exists
|
||||
if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
|
||||
(BrushOrigin == NULL) && (rop4 == 0) )
|
||||
{
|
||||
canCopyBits = TRUE;
|
||||
} else
|
||||
canCopyBits = FALSE;
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
|
||||
// FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's
|
||||
// format. Call DrvDitherColor function where necessary and if available
|
||||
// If we don't have to do anything special, we can punt to DrvCopyBits
|
||||
// if it exists
|
||||
if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
|
||||
(BrushOrigin == NULL) && (rop4 == 0) )
|
||||
{
|
||||
canCopyBits = TRUE;
|
||||
} else
|
||||
canCopyBits = FALSE;
|
||||
|
||||
// FIXME: If canCopyBits == TRUE AND the driver has a DrvCopyBits then
|
||||
// punt to EngCopyBits and not the driver's DrvCopyBits just yet so
|
||||
// that the EngCopyBits can take care of the clipping drivers
|
||||
// DrvCopyBits
|
||||
// Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
|
||||
// * The destination bitmap is not managed by the GDI OR
|
||||
if(Dest->iType != STYPE_BITMAP)
|
||||
{
|
||||
// Destination surface is device managed
|
||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
|
||||
// FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd
|
||||
// function to go there instead of the Engine's bltting function
|
||||
// so as to do the clipping for the driver
|
||||
if (DestGDI->BitBlt!=NULL)
|
||||
{
|
||||
// The destination is device managed, therefore get the source into a format compatible surface
|
||||
TempPoint.x = 0;
|
||||
TempPoint.y = 0;
|
||||
TempRect.top = 0;
|
||||
TempRect.left = 0;
|
||||
TempRect.bottom = DestRect->bottom - DestRect->top;
|
||||
TempRect.right = DestRect->right - DestRect->left;
|
||||
TempSize.cx = TempRect.right;
|
||||
TempSize.cy = TempRect.bottom;
|
||||
|
||||
// Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap
|
||||
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
||||
{
|
||||
// Destination surface is device managed
|
||||
if(Dest->iType!=STYPE_BITMAP)
|
||||
{
|
||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
hTemp = EngCreateBitmap(TempSize,
|
||||
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
|
||||
Dest->iBitmapFormat, 0, NULL);
|
||||
TempSurf = AccessUserObject(hTemp);
|
||||
|
||||
if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
|
||||
{
|
||||
return DestGDI->CopyBits(Dest, Source, ClipRegion,
|
||||
ColorTranslation, DestRect, SourcePoint);
|
||||
}
|
||||
// FIXME: Skip creating a TempSurf if we have the same BPP and palette
|
||||
EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0);
|
||||
|
||||
if (DestGDI->BitBlt!=NULL)
|
||||
{
|
||||
return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion,
|
||||
ColorTranslation, DestRect, SourcePoint,
|
||||
MaskRect, Brush, BrushOrigin, rop4);
|
||||
}
|
||||
}
|
||||
return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
|
||||
NULL, DestRect, &TempPoint,
|
||||
MaskRect, Brush, BrushOrigin, rop4);
|
||||
}
|
||||
}
|
||||
|
||||
// Source surface is device managed
|
||||
if(Source->iType!=STYPE_BITMAP)
|
||||
{
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
// * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
|
||||
if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
|
||||
{
|
||||
if (SourceGDI->BitBlt!=NULL)
|
||||
{
|
||||
// Request the device driver to return the bitmap in a format compatible with the device
|
||||
return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
|
||||
NULL, DestRect, SourcePoint,
|
||||
MaskRect, Brush, BrushOrigin, rop4);
|
||||
|
||||
if ((SourceGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
|
||||
{
|
||||
return SourceGDI->CopyBits(Dest, Source, ClipRegion,
|
||||
ColorTranslation, DestRect, SourcePoint);
|
||||
}
|
||||
// Convert the surface from the driver into the required destination surface
|
||||
}
|
||||
}
|
||||
|
||||
if (SourceGDI->BitBlt!=NULL)
|
||||
{
|
||||
return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
|
||||
ColorTranslation, DestRect, SourcePoint,
|
||||
MaskRect, Brush, BrushOrigin, rop4);
|
||||
}
|
||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
|
||||
// Determine clipping type
|
||||
if (ClipRegion == (CLIPOBJ *) NULL)
|
||||
{
|
||||
clippingType = DC_TRIVIAL;
|
||||
} else {
|
||||
clippingType = ClipRegion->iDComplexity;
|
||||
}
|
||||
|
||||
// Should never get here, if it's not GDI managed then the device
|
||||
// should take care of it
|
||||
// We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
|
||||
switch(clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
||||
return(TRUE);
|
||||
|
||||
// FIXME: Error message here
|
||||
}
|
||||
case DC_RECT:
|
||||
|
||||
}
|
||||
// Clip the blt to the clip rectangle
|
||||
EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
|
||||
|
||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
||||
|
||||
// Determine clipping type
|
||||
if (ClipRegion == (CLIPOBJ *) NULL)
|
||||
{
|
||||
clippingType = DC_TRIVIAL;
|
||||
} else {
|
||||
clippingType = ClipRegion->iDComplexity;
|
||||
}
|
||||
return(TRUE);
|
||||
|
||||
// We don't handle color translation just yet
|
||||
case DC_COMPLEX:
|
||||
|
||||
if ((rop4 == 0x0000CCCC) &&
|
||||
((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
|
||||
{
|
||||
switch(clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
BitBltCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
DestRect, SourcePoint, Source->lDelta);
|
||||
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
return(TRUE);
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||
|
||||
case DC_RECT:
|
||||
if (RectEnum.c > 0)
|
||||
{
|
||||
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
||||
RECTL* prcl = &RectEnum.arcl[0];
|
||||
|
||||
// Clip the blt to the clip rectangle
|
||||
do {
|
||||
EngIntersectRect(prcl, prcl, DestRect);
|
||||
|
||||
EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
|
||||
ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
|
||||
|
||||
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
||||
prcl++;
|
||||
|
||||
BitBltCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
&rclTmp, &ptlTmp, Source->lDelta);
|
||||
} while (prcl < prclEnd);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
} while(EnumMore);
|
||||
|
||||
case DC_COMPLEX:
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES,
|
||||
CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
|
||||
(PVOID) &RectEnum);
|
||||
|
||||
if (RectEnum.c > 0)
|
||||
{
|
||||
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
||||
RECTL* prcl = &RectEnum.arcl[0];
|
||||
|
||||
do {
|
||||
EngIntersectRect(prcl, prcl, DestRect);
|
||||
|
||||
ptlTmp.x = SourcePoint->x + prcl->left
|
||||
- DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + prcl->top
|
||||
- DestRect->top;
|
||||
|
||||
BitBltCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
prcl, &ptlTmp, Source->lDelta);
|
||||
|
||||
prcl++;
|
||||
|
||||
} while (prcl < prclEnd);
|
||||
}
|
||||
|
||||
} while(EnumMore);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return(FALSE);
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
PVOID BRUSHOBJ_pvAllocRbrush(IN PBRUSHOBJ BrushObj,
|
||||
IN ULONG ObjSize)
|
||||
{
|
||||
BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
|
||||
return BrushObj->pvRbrush;
|
||||
BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
|
||||
return BrushObj->pvRbrush;
|
||||
}
|
||||
|
||||
PVOID BRUSHOBJ_pvGetRbrush(IN PBRUSHOBJ BrushObj)
|
||||
{
|
||||
return BrushObj->pvRbrush;
|
||||
return BrushObj->pvRbrush;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
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
|
||||
// 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
|
||||
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
|
||||
|
|
|
@ -18,109 +18,109 @@
|
|||
CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
|
||||
ULONG Mode, ULONG Options)
|
||||
{
|
||||
HCLIP NewClip;
|
||||
CLIPOBJ *ClipObj;
|
||||
CLIPGDI *ClipGDI;
|
||||
HCLIP NewClip;
|
||||
CLIPOBJ *ClipObj;
|
||||
CLIPGDI *ClipGDI;
|
||||
|
||||
ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
||||
ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
|
||||
ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
||||
ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
|
||||
|
||||
NewClip = CreateGDIHandle(ClipGDI, ClipObj);
|
||||
NewClip = CreateGDIHandle(ClipGDI, ClipObj);
|
||||
|
||||
ClipGDI->NumRegionRects = NumRects;
|
||||
ClipGDI->RegionRects = Rects;
|
||||
ClipObj->iMode = Mode;
|
||||
ClipObj->fjOptions = Options;
|
||||
ClipObj->iDComplexity = DC_TRIVIAL;
|
||||
ClipGDI->NumRegionRects = NumRects;
|
||||
ClipGDI->RegionRects = Rects;
|
||||
ClipObj->iMode = Mode;
|
||||
ClipObj->fjOptions = Options;
|
||||
ClipObj->iDComplexity = DC_TRIVIAL;
|
||||
|
||||
if(NumRects == 1)
|
||||
{
|
||||
ClipObj->iFComplexity = FC_RECT;
|
||||
ClipObj->iDComplexity = DC_RECT;
|
||||
if(NumRects == 1)
|
||||
{
|
||||
ClipObj->iFComplexity = FC_RECT;
|
||||
ClipObj->iDComplexity = DC_RECT;
|
||||
|
||||
// FIXME: Is this correct??
|
||||
ClipObj->rclBounds = Rects[0];
|
||||
} else
|
||||
{
|
||||
ClipObj->iDComplexity = DC_COMPLEX;
|
||||
if(NumRects <= 4)
|
||||
{
|
||||
ClipObj->iFComplexity = FC_RECT4;
|
||||
} else
|
||||
{
|
||||
ClipObj->iFComplexity = FC_COMPLEX;
|
||||
}
|
||||
}
|
||||
// FIXME: Is this correct??
|
||||
ClipObj->rclBounds = Rects[0];
|
||||
} else
|
||||
{
|
||||
ClipObj->iDComplexity = DC_COMPLEX;
|
||||
if(NumRects <= 4)
|
||||
{
|
||||
ClipObj->iFComplexity = FC_RECT4;
|
||||
} else
|
||||
{
|
||||
ClipObj->iFComplexity = FC_COMPLEX;
|
||||
}
|
||||
}
|
||||
|
||||
return ClipObj;
|
||||
return ClipObj;
|
||||
}
|
||||
|
||||
VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)
|
||||
{
|
||||
HCLIP HClip = AccessHandleFromUserObject(ClipObj);
|
||||
CLIPGDI *ClipGDI = AccessInternalObject(HClip);
|
||||
HCLIP HClip = AccessHandleFromUserObject(ClipObj);
|
||||
CLIPGDI *ClipGDI = AccessInternalObject(HClip);
|
||||
|
||||
EngFreeMem(ClipGDI);
|
||||
EngFreeMem(ClipObj);
|
||||
FreeGDIHandle(HClip);
|
||||
EngFreeMem(ClipGDI);
|
||||
EngFreeMem(ClipObj);
|
||||
FreeGDIHandle(HClip);
|
||||
}
|
||||
|
||||
VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects)
|
||||
{
|
||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||
|
||||
ClipGDI->NumIntersectRects = NumRects;
|
||||
ClipGDI->IntersectRects = IntersectRects;
|
||||
ClipGDI->NumIntersectRects = NumRects;
|
||||
ClipGDI->IntersectRects = IntersectRects;
|
||||
|
||||
if(NumRects == 1)
|
||||
{
|
||||
ClipObj->iDComplexity = DC_RECT;
|
||||
ClipObj->rclBounds = IntersectRects[0];
|
||||
} else
|
||||
{
|
||||
ClipObj->iDComplexity = DC_COMPLEX;
|
||||
ClipGDI->IntersectRects = IntersectRects;
|
||||
}
|
||||
if(NumRects == 1)
|
||||
{
|
||||
ClipObj->iDComplexity = DC_RECT;
|
||||
ClipObj->rclBounds = IntersectRects[0];
|
||||
} else
|
||||
{
|
||||
ClipObj->iDComplexity = DC_COMPLEX;
|
||||
ClipGDI->IntersectRects = IntersectRects;
|
||||
}
|
||||
}
|
||||
|
||||
CLIPOBJ *EngCreateClip(VOID)
|
||||
{
|
||||
return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
||||
return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
||||
}
|
||||
|
||||
VOID EngDeleteClip(CLIPOBJ *ClipRegion)
|
||||
{
|
||||
EngFreeMem(ClipRegion);
|
||||
EngFreeMem(ClipRegion);
|
||||
}
|
||||
|
||||
ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj, IN BOOL ShouldDoAll,
|
||||
IN ULONG ClipType, IN ULONG BuildOrder,
|
||||
IN ULONG MaxRects)
|
||||
{
|
||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||
|
||||
ClipGDI->EnumPos = 0;
|
||||
ClipGDI->EnumRects.c = MaxRects;
|
||||
ClipGDI->EnumPos = 0;
|
||||
ClipGDI->EnumRects.c = MaxRects;
|
||||
|
||||
// Return the number of rectangles enumerated
|
||||
if(ClipGDI->EnumRects.c>MaxRects)
|
||||
{
|
||||
ClipGDI->EnumRects.c = 0xFFFFFFFF;
|
||||
}
|
||||
// Return the number of rectangles enumerated
|
||||
if(ClipGDI->EnumRects.c>MaxRects)
|
||||
{
|
||||
ClipGDI->EnumRects.c = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return ClipGDI->EnumRects.c;
|
||||
return ClipGDI->EnumRects.c;
|
||||
}
|
||||
|
||||
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize,
|
||||
OUT ULONG *EnumRects)
|
||||
{
|
||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||
|
||||
ClipGDI->EnumPos++;
|
||||
ClipGDI->EnumPos++;
|
||||
|
||||
if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
|
||||
{
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
|
||||
{
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -11,192 +11,153 @@
|
|||
#include <ddk/winddi.h>
|
||||
#include "objects.h"
|
||||
#include "enum.h"
|
||||
#include "../dib/dib.h"
|
||||
|
||||
VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||
PRECTL DestRect, POINTL *SourcePoint,
|
||||
ULONG Delta, XLATEOBJ *ColorTranslation)
|
||||
BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||
PRECTL DestRect, POINTL *SourcePoint,
|
||||
ULONG Delta, XLATEOBJ *ColorTranslation)
|
||||
{
|
||||
ULONG dy, leftOfSource, leftOfDest, Width, SourceBPP, DestBPP, RGBulong = 0, idxColor, i, TrivialCopy = 0;
|
||||
BYTE *SourcePos, *SourceInitial, *DestPos, *DestInitial;
|
||||
ULONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel;
|
||||
|
||||
// FIXME: Get ColorTranslation passed here and do something with it
|
||||
PFN_DIB_GetPixel Source_DIB_GetPixel;
|
||||
PFN_DIB_PutPixel Dest_DIB_PutPixel;
|
||||
|
||||
if(ColorTranslation == NULL)
|
||||
{
|
||||
TrivialCopy = 1;
|
||||
} else if(ColorTranslation->flXlate & XO_TRIVIAL)
|
||||
{
|
||||
TrivialCopy = 1;
|
||||
}
|
||||
DestWidth = DestRect->right - DestRect->left;
|
||||
DestHeight = DestRect->bottom - DestRect->top;
|
||||
CurrentSourceCol = SourcePoint->x;
|
||||
CurrentSourceLine = SourcePoint->y;
|
||||
|
||||
leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
|
||||
leftOfDest = DestRect->left * DestGDI->BytesPerPixel;
|
||||
Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
|
||||
// Assign GetPixel DIB function according to bytes per pixel
|
||||
switch(DestGDI->BitsPerPixel)
|
||||
{
|
||||
case 4:
|
||||
return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
|
||||
DestRect, SourcePoint, Delta, ColorTranslation);
|
||||
break;
|
||||
|
||||
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);
|
||||
case 24:
|
||||
return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
|
||||
DestRect, SourcePoint, Delta, ColorTranslation);
|
||||
break;
|
||||
|
||||
SourcePos = SourceSurf->pvBits +
|
||||
(SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP);
|
||||
SourceInitial = SourcePos;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
||||
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
||||
RECTL *DestRect, POINTL *SourcePoint)
|
||||
{
|
||||
SURFGDI *DestGDI, *SourceGDI;
|
||||
BYTE clippingType;
|
||||
RECTL rclTmp;
|
||||
POINTL ptlTmp;
|
||||
RECT_ENUM RectEnum;
|
||||
BOOL EnumMore;
|
||||
SURFGDI *DestGDI, *SourceGDI;
|
||||
BYTE clippingType;
|
||||
RECTL rclTmp;
|
||||
POINTL ptlTmp;
|
||||
RECT_ENUM RectEnum;
|
||||
BOOL EnumMore;
|
||||
|
||||
// FIXME: Do color translation -- refer to eng\bitblt.c
|
||||
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
|
||||
// mark the copy block function to be DrvCopyBits instead of the
|
||||
// GDI's copy bit function so as to remove clipping from the
|
||||
// driver's responsibility
|
||||
|
||||
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
|
||||
// mark the copy block function to be DrvCopyBits instead of the
|
||||
// GDI's copy bit function so as to remove clipping from the
|
||||
// driver's responsibility
|
||||
// If one of the surfaces isn't managed by the GDI
|
||||
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
||||
{
|
||||
// Destination surface is device managed
|
||||
if(Dest->iType!=STYPE_BITMAP)
|
||||
{
|
||||
DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
|
||||
|
||||
// If one of the surfaces isn't managed by the GDI
|
||||
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
||||
{
|
||||
|
||||
// Destination surface is device managed
|
||||
if(Dest->iType!=STYPE_BITMAP)
|
||||
if (DestGDI->CopyBits!=NULL)
|
||||
{
|
||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||
|
||||
if (DestGDI->CopyBits!=NULL)
|
||||
{
|
||||
return DestGDI->CopyBits(Dest, Source, Clip,
|
||||
ColorTranslation, DestRect, SourcePoint);
|
||||
}
|
||||
return DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
|
||||
}
|
||||
}
|
||||
|
||||
// Source surface is device managed
|
||||
if(Source->iType!=STYPE_BITMAP)
|
||||
// Source surface is device managed
|
||||
if(Source->iType!=STYPE_BITMAP)
|
||||
{
|
||||
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
||||
|
||||
if (SourceGDI->CopyBits!=NULL)
|
||||
{
|
||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||
|
||||
if (SourceGDI->CopyBits!=NULL)
|
||||
{
|
||||
return SourceGDI->CopyBits(Dest, Source, Clip,
|
||||
ColorTranslation, DestRect, SourcePoint);
|
||||
}
|
||||
return SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
|
||||
}
|
||||
}
|
||||
|
||||
// If CopyBits wasn't hooked, BitBlt must be
|
||||
return EngBitBlt(Dest, Source,
|
||||
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
// If CopyBits wasn't hooked, BitBlt must be
|
||||
return EngBitBlt(Dest, Source,
|
||||
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
// Determine clipping type
|
||||
if (Clip == (CLIPOBJ *) NULL)
|
||||
{
|
||||
clippingType = DC_TRIVIAL;
|
||||
} else {
|
||||
clippingType = Clip->iDComplexity;
|
||||
}
|
||||
// Determine clipping type
|
||||
if (Clip == (CLIPOBJ *) NULL)
|
||||
{
|
||||
clippingType = DC_TRIVIAL;
|
||||
} else {
|
||||
clippingType = Clip->iDComplexity;
|
||||
}
|
||||
|
||||
// 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);
|
||||
// We only handle XO_TABLE translations at the momement
|
||||
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
|
||||
(ColorTranslation->flXlate & XO_TABLE))
|
||||
{
|
||||
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
||||
DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
|
||||
|
||||
switch(clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
CopyBitsCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
||||
switch(clippingType)
|
||||
{
|
||||
case DC_TRIVIAL:
|
||||
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
||||
return(TRUE);
|
||||
|
||||
return(TRUE);
|
||||
case DC_RECT:
|
||||
// Clip the blt to the clip rectangle
|
||||
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
|
||||
|
||||
case DC_RECT:
|
||||
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
||||
|
||||
// Clip the blt to the clip rectangle
|
||||
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
|
||||
|
||||
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
|
||||
return(TRUE);
|
||||
|
||||
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
||||
case DC_COMPLEX:
|
||||
|
||||
CopyBitsCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
&rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
return(TRUE);
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||
|
||||
case DC_COMPLEX:
|
||||
|
||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
||||
CD_ANY, ENUM_RECT_LIMIT);
|
||||
if (RectEnum.c > 0)
|
||||
{
|
||||
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
||||
RECTL* prcl = &RectEnum.arcl[0];
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum),
|
||||
(PVOID) &RectEnum);
|
||||
EngIntersectRect(prcl, prcl, DestRect);
|
||||
|
||||
if (RectEnum.c > 0)
|
||||
{
|
||||
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
||||
RECTL* prcl = &RectEnum.arcl[0];
|
||||
ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
|
||||
|
||||
do {
|
||||
EngIntersectRect(prcl, prcl, DestRect);
|
||||
if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
|
||||
prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
|
||||
|
||||
ptlTmp.x = SourcePoint->x + prcl->left
|
||||
- DestRect->left;
|
||||
ptlTmp.y = SourcePoint->y + prcl->top
|
||||
- DestRect->top;
|
||||
prcl++;
|
||||
|
||||
CopyBitsCopy(Dest, Source,
|
||||
DestGDI, SourceGDI,
|
||||
prcl, &ptlTmp, Source->lDelta, ColorTranslation);
|
||||
} while (prcl < prclEnd);
|
||||
}
|
||||
|
||||
prcl++;
|
||||
} while(EnumMore);
|
||||
|
||||
} while (prcl < prclEnd);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
} while(EnumMore);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -11,40 +11,33 @@
|
|||
#include <ddk/ntddk.h>
|
||||
|
||||
DWORD STDCALL EngDeviceIoControl(
|
||||
HANDLE hDevice,
|
||||
DWORD dwIoControlCode,
|
||||
LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize,
|
||||
LPVOID lpOutBuffer,
|
||||
DWORD nOutBufferSize,
|
||||
DWORD *lpBytesReturned)
|
||||
HANDLE hDevice,
|
||||
DWORD dwIoControlCode,
|
||||
LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize,
|
||||
LPVOID lpOutBuffer,
|
||||
DWORD nOutBufferSize,
|
||||
DWORD *lpBytesReturned)
|
||||
{
|
||||
PIRP Irp;
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PIRP Irp;
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
|
||||
DriverObject = hDevice;
|
||||
DriverObject = hDevice;
|
||||
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode,
|
||||
DriverObject->DeviceObject,
|
||||
lpInBuffer,
|
||||
nInBufferSize,
|
||||
lpOutBuffer,
|
||||
nOutBufferSize,
|
||||
FALSE,
|
||||
&Event,
|
||||
&Iosb);
|
||||
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, DriverObject->DeviceObject, lpInBuffer, nInBufferSize,
|
||||
lpOutBuffer, nOutBufferSize, FALSE, &Event, &Iosb);
|
||||
|
||||
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
|
||||
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
|
||||
}
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
|
||||
}
|
||||
|
||||
return (Status);
|
||||
return (Status);
|
||||
}
|
||||
|
|
|
@ -16,19 +16,19 @@ ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj,
|
|||
IN ULONG BuildOrder,
|
||||
IN ULONG MaxRects)
|
||||
{
|
||||
// Sets the parameters for enumerating rectables in the given clip region
|
||||
// Sets the parameters for enumerating rectables in the given clip region
|
||||
|
||||
ULONG enumCount = 0;
|
||||
ENUMRECTS enumRects;
|
||||
ULONG enumCount = 0;
|
||||
ENUMRECTS enumRects;
|
||||
|
||||
// MUCH WORK TO DO HERE
|
||||
// MUCH WORK TO DO HERE
|
||||
|
||||
// Return the number of rectangles enumerated
|
||||
if(enumCount>MaxRects)
|
||||
{
|
||||
enumCount = 0xFFFFFFFF;
|
||||
}
|
||||
return enumCount;
|
||||
// Return the number of rectangles enumerated
|
||||
if(enumCount>MaxRects)
|
||||
{
|
||||
enumCount = 0xFFFFFFFF;
|
||||
}
|
||||
return enumCount;
|
||||
}
|
||||
|
||||
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
typedef struct _RECT_ENUM
|
||||
{
|
||||
ULONG c;
|
||||
RECTL arcl[ENUM_RECT_LIMIT];
|
||||
ULONG c;
|
||||
RECTL arcl[ENUM_RECT_LIMIT];
|
||||
} RECT_ENUM;
|
||||
|
|
|
@ -18,52 +18,50 @@
|
|||
|
||||
ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject)
|
||||
{
|
||||
ULONG NewHandle = HandleCounter++;
|
||||
ULONG NewHandle = HandleCounter++;
|
||||
|
||||
GDIHandles[NewHandle].InternalObject = InternalObject;
|
||||
GDIHandles[NewHandle].UserObject = UserObject;
|
||||
GDIHandles[NewHandle].InternalObject = InternalObject;
|
||||
GDIHandles[NewHandle].UserObject = UserObject;
|
||||
|
||||
return NewHandle;
|
||||
return NewHandle;
|
||||
}
|
||||
|
||||
VOID FreeGDIHandle(ULONG Handle)
|
||||
{
|
||||
GDIHandles[Handle].InternalObject = NULL;
|
||||
GDIHandles[Handle].UserObject = NULL;
|
||||
GDIHandles[Handle].InternalObject = NULL;
|
||||
GDIHandles[Handle].UserObject = NULL;
|
||||
}
|
||||
|
||||
PVOID AccessInternalObject(ULONG Handle)
|
||||
{
|
||||
return GDIHandles[Handle].InternalObject;
|
||||
return GDIHandles[Handle].InternalObject;
|
||||
}
|
||||
|
||||
PVOID AccessUserObject(ULONG Handle)
|
||||
{
|
||||
return GDIHandles[Handle].UserObject;
|
||||
return GDIHandles[Handle].UserObject;
|
||||
}
|
||||
|
||||
PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
for(i=0; i<MAX_GDI_HANDLES; i++)
|
||||
{
|
||||
if(GDIHandles[i].UserObject == UserObject)
|
||||
return GDIHandles[i].InternalObject;
|
||||
}
|
||||
for(i=0; i<MAX_GDI_HANDLES; i++)
|
||||
{
|
||||
if(GDIHandles[i].UserObject == UserObject) return GDIHandles[i].InternalObject;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ULONG AccessHandleFromUserObject(PVOID UserObject)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
for(i=0; i<MAX_GDI_HANDLES; i++)
|
||||
{
|
||||
if(GDIHandles[i].UserObject == UserObject)
|
||||
return i;
|
||||
}
|
||||
for(i=0; i<MAX_GDI_HANDLES; i++)
|
||||
{
|
||||
if(GDIHandles[i].UserObject == UserObject) return i;
|
||||
}
|
||||
|
||||
return INVALID_HANDLE;
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
*/
|
||||
|
||||
typedef struct _GDI_HANDLE {
|
||||
ULONG Handle;
|
||||
PVOID InternalObject;
|
||||
PVOID UserObject;
|
||||
ULONG Handle;
|
||||
PVOID InternalObject;
|
||||
PVOID UserObject;
|
||||
} GDI_HANDLE, *PGDI_HANDLE;
|
||||
|
||||
#define INVALID_HANDLE 0
|
||||
|
|
|
@ -1,111 +1,118 @@
|
|||
#include <ddk/winddi.h>
|
||||
#include "objects.h"
|
||||
#include "../dib/dib.h"
|
||||
|
||||
// POSSIBLE FIXME: Switch X and Y's so that drawing a line doesn't try to draw from 150 to 50 (negative dx)
|
||||
|
||||
VOID LinePoint(SURFOBJ *Surface, SURFGDI *SurfGDI,
|
||||
LONG x, LONG y, ULONG iColor)
|
||||
{
|
||||
ULONG offset;
|
||||
|
||||
offset = (Surface->lDelta*y)+(x*SurfGDI->BytesPerPixel);
|
||||
|
||||
memcpy(Surface->pvBits+offset,
|
||||
&iColor, SurfGDI->BytesPerPixel);
|
||||
}
|
||||
|
||||
BOOL EngHLine(SURFOBJ *Surface, SURFGDI *SurfGDI,
|
||||
LONG x, LONG y, LONG len, ULONG iColor)
|
||||
{
|
||||
ULONG offset, ix;
|
||||
|
||||
offset = (Surface->lDelta*y)+(x*SurfGDI->BytesPerPixel);
|
||||
|
||||
for(ix=0; ix<len*SurfGDI->BytesPerPixel; ix+=SurfGDI->BytesPerPixel)
|
||||
memcpy(Surface->pvBits+offset+ix,
|
||||
&iColor, SurfGDI->BytesPerPixel);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
|
||||
LONG x1, LONG y1, LONG x2, LONG y2,
|
||||
RECTL *RectBounds, MIX mix)
|
||||
{
|
||||
SURFGDI *SurfGDI;
|
||||
LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error;
|
||||
SURFGDI *SurfGDI;
|
||||
LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
|
||||
|
||||
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
||||
// These functions are assigned if we're working with a DIB
|
||||
// The assigned functions depend on the bitsPerPixel of the DIB
|
||||
PFN_DIB_PutPixel DIB_PutPixel;
|
||||
PFN_DIB_HLine DIB_HLine;
|
||||
PFN_DIB_VLine DIB_VLine;
|
||||
|
||||
if(Surface->iType!=STYPE_BITMAP)
|
||||
{
|
||||
// Call the driver's DrvLineTo
|
||||
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2,
|
||||
RectBounds, mix);
|
||||
}
|
||||
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
||||
|
||||
// FIXME: Implement clipping
|
||||
if(Surface->iType!=STYPE_BITMAP)
|
||||
{
|
||||
// Call the driver's DrvLineTo
|
||||
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
||||
}
|
||||
|
||||
if(y1==y2) return EngHLine(Surface, SurfGDI, x1, y1, (x2-x1), Brush->iSolidColor);
|
||||
// Assign DIB functions according to bytes per pixel
|
||||
switch(BitsPerFormat(Surface->iBitmapFormat))
|
||||
{
|
||||
case 4:
|
||||
DIB_PutPixel = DIB_4BPP_PutPixel;
|
||||
DIB_HLine = DIB_4BPP_HLine;
|
||||
DIB_VLine = DIB_4BPP_VLine;
|
||||
break;
|
||||
|
||||
x=x1;
|
||||
y=y1;
|
||||
deltax=x2-x1;
|
||||
deltay=y2-y1;
|
||||
case 24:
|
||||
DIB_PutPixel = DIB_24BPP_PutPixel;
|
||||
DIB_HLine = DIB_24BPP_HLine;
|
||||
DIB_VLine = DIB_24BPP_VLine;
|
||||
break;
|
||||
|
||||
if(deltax<0)
|
||||
{
|
||||
xchange=-1;
|
||||
deltax=-deltax;
|
||||
} else
|
||||
{
|
||||
xchange=1;
|
||||
}
|
||||
default:
|
||||
DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
|
||||
BitsPerFormat(Surface->iBitmapFormat));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(deltay<0)
|
||||
{
|
||||
ychange=-1;
|
||||
deltay=-deltay;
|
||||
} else
|
||||
{
|
||||
ychange=1;
|
||||
};
|
||||
// FIXME: Implement clipping
|
||||
|
||||
x=x1;
|
||||
y=y1;
|
||||
deltax=x2-x1;
|
||||
deltay=y2-y1;
|
||||
|
||||
if(deltax<0)
|
||||
{
|
||||
xchange=-1;
|
||||
deltax=-deltax;
|
||||
hx = x2;
|
||||
} else
|
||||
{
|
||||
xchange=1;
|
||||
hx = x1;
|
||||
}
|
||||
|
||||
if(deltay<0)
|
||||
{
|
||||
ychange=-1;
|
||||
deltay=-deltay;
|
||||
vy = y2;
|
||||
} else
|
||||
{
|
||||
ychange=1;
|
||||
vy = y1;
|
||||
}
|
||||
|
||||
if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); return TRUE; }
|
||||
if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); return TRUE; }
|
||||
|
||||
error=0;
|
||||
i=0;
|
||||
|
||||
if(deltax<deltay)
|
||||
{
|
||||
length=deltay+1;
|
||||
while(i<length)
|
||||
{
|
||||
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
|
||||
y=y+ychange;
|
||||
error=error+deltax;
|
||||
length=deltay+1;
|
||||
while(i<length)
|
||||
{
|
||||
DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
|
||||
y=y+ychange;
|
||||
error=error+deltax;
|
||||
|
||||
if(error>deltay)
|
||||
{
|
||||
x=x+xchange;
|
||||
error=error-deltay;
|
||||
}
|
||||
i=i+1;
|
||||
}
|
||||
if(error>deltay)
|
||||
{
|
||||
x=x+xchange;
|
||||
error=error-deltay;
|
||||
}
|
||||
i=i+1;
|
||||
}
|
||||
} else
|
||||
{
|
||||
length=deltax+1;
|
||||
while(i<length)
|
||||
{
|
||||
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
|
||||
x=x+xchange;
|
||||
error=error+deltay;
|
||||
if(error>deltax)
|
||||
{
|
||||
y=y+ychange;
|
||||
error=error-deltax;
|
||||
}
|
||||
i=i+1;
|
||||
DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
|
||||
x=x+xchange;
|
||||
error=error+deltay;
|
||||
if(error>deltax)
|
||||
{
|
||||
y=y+ychange;
|
||||
error=error-deltax;
|
||||
}
|
||||
}
|
||||
i=i+1;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -13,35 +13,34 @@
|
|||
|
||||
PVOID STDCALL EngAllocMem(ULONG Flags, ULONG MemSize, ULONG Tag)
|
||||
{
|
||||
PVOID newMem;
|
||||
PVOID newMem;
|
||||
|
||||
newMem = ExAllocatePoolWithTag(NonPagedPool, MemSize, Tag); // FIXME: Use PagedPool when it is implemented
|
||||
newMem = ExAllocatePoolWithTag(NonPagedPool, MemSize, Tag); // FIXME: Use PagedPool when it is implemented
|
||||
|
||||
if(Flags == FL_ZERO_MEMORY)
|
||||
{
|
||||
RtlZeroMemory(newMem, MemSize);
|
||||
}
|
||||
if(Flags == FL_ZERO_MEMORY)
|
||||
{
|
||||
RtlZeroMemory(newMem, MemSize);
|
||||
}
|
||||
|
||||
return newMem;
|
||||
return newMem;
|
||||
}
|
||||
|
||||
VOID STDCALL EngFreeMem(PVOID Mem)
|
||||
{
|
||||
ExFreePool(Mem);
|
||||
ExFreePool(Mem);
|
||||
}
|
||||
|
||||
PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag)
|
||||
{
|
||||
/* PVOID newMem;
|
||||
/* PVOID newMem;
|
||||
|
||||
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
|
||||
MEM_COMMIT, PAGE_READWRITE); */
|
||||
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
|
||||
MEM_COMMIT, PAGE_READWRITE); */
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID STDCALL EngFreeUserMem(PVOID pv)
|
||||
{
|
||||
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
|
||||
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
|
||||
}
|
||||
|
||||
|
|
|
@ -13,18 +13,18 @@ typedef struct _BRUSHGDI {
|
|||
} BRUSHGDI;
|
||||
|
||||
typedef struct _CLIPGDI {
|
||||
ULONG NumRegionRects;
|
||||
ULONG NumIntersectRects;
|
||||
RECTL *RegionRects;
|
||||
RECTL *IntersectRects;
|
||||
ULONG NumRegionRects;
|
||||
ULONG NumIntersectRects;
|
||||
RECTL *RegionRects;
|
||||
RECTL *IntersectRects;
|
||||
|
||||
ULONG EnumPos;
|
||||
ENUMRECTS EnumRects;
|
||||
ULONG EnumPos;
|
||||
ENUMRECTS EnumRects;
|
||||
} CLIPGDI, *PCLIPGDI;
|
||||
|
||||
typedef struct _DRVFUNCTIONSGDI {
|
||||
HDEV hdev;
|
||||
DRVFN Functions[INDEX_LAST];
|
||||
HDEV hdev;
|
||||
DRVFN Functions[INDEX_LAST];
|
||||
} DRVFUNCTIONSGDI;
|
||||
|
||||
typedef struct _FLOATGDI {
|
||||
|
@ -36,12 +36,12 @@ typedef struct _FONTGDI {
|
|||
} FONTGDI;
|
||||
|
||||
typedef struct _PALGDI {
|
||||
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
|
||||
ULONG NumColors;
|
||||
ULONG *IndexedColors;
|
||||
ULONG RedMask;
|
||||
ULONG GreenMask;
|
||||
ULONG BlueMask;
|
||||
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
|
||||
ULONG NumColors;
|
||||
ULONG *IndexedColors;
|
||||
ULONG RedMask;
|
||||
ULONG GreenMask;
|
||||
ULONG BlueMask;
|
||||
} PALGDI, *PPALGDI;
|
||||
|
||||
typedef struct _PATHGDI {
|
||||
|
@ -88,21 +88,24 @@ typedef VOID (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL);
|
|||
|
||||
typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
|
||||
|
||||
typedef struct _SURFGDI {
|
||||
BYTE BytesPerPixel;
|
||||
typedef BOOL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG);
|
||||
|
||||
PFN_BitBlt BitBlt;
|
||||
PFN_StretchBlt StretchBlt;
|
||||
PFN_TextOut TextOut;
|
||||
PFN_Paint Paint;
|
||||
PFN_StrokePath StrokePath;
|
||||
PFN_FillPath FillPath;
|
||||
PFN_StrokeAndFillPath StrokeAndFillPath;
|
||||
PFN_LineTo LineTo;
|
||||
PFN_CopyBits CopyBits;
|
||||
PFN_Synchronize Synchronize;
|
||||
BOOL SynchronizeAccess;
|
||||
PFN_CreateDeviceBitmap CreateDeviceBitmap;
|
||||
typedef struct _SURFGDI {
|
||||
INT BitsPerPixel;
|
||||
|
||||
PFN_BitBlt BitBlt;
|
||||
PFN_StretchBlt StretchBlt;
|
||||
PFN_TextOut TextOut;
|
||||
PFN_Paint Paint;
|
||||
PFN_StrokePath StrokePath;
|
||||
PFN_FillPath FillPath;
|
||||
PFN_StrokeAndFillPath StrokeAndFillPath;
|
||||
PFN_LineTo LineTo;
|
||||
PFN_CopyBits CopyBits;
|
||||
PFN_Synchronize Synchronize;
|
||||
BOOL SynchronizeAccess;
|
||||
PFN_CreateDeviceBitmap CreateDeviceBitmap;
|
||||
PFN_SetPalette SetPalette;
|
||||
} SURFGDI, *PSURFGDI;
|
||||
|
||||
typedef struct _XFORMGDI {
|
||||
|
@ -110,10 +113,10 @@ typedef struct _XFORMGDI {
|
|||
} XFORMGDI;
|
||||
|
||||
typedef struct _XLATEGDI {
|
||||
HPALETTE DestPal;
|
||||
HPALETTE SourcePal;
|
||||
HPALETTE DestPal;
|
||||
HPALETTE SourcePal;
|
||||
|
||||
ULONG *translationTable;
|
||||
ULONG *translationTable;
|
||||
} XLATEGDI;
|
||||
|
||||
// List of GDI objects
|
||||
|
|
|
@ -15,80 +15,75 @@
|
|||
|
||||
BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
|
||||
{
|
||||
ULONG x, y, LineWidth, leftOfBitmap;
|
||||
SURFGDI *SurfaceGDI;
|
||||
ULONG x, y, LineWidth, leftOfBitmap;
|
||||
SURFGDI *SurfaceGDI;
|
||||
|
||||
SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
|
||||
LineWidth = Dimensions->right - Dimensions->left;
|
||||
SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
|
||||
LineWidth = Dimensions->right - Dimensions->left;
|
||||
|
||||
for (y = Dimensions->top; y < Dimensions->bottom; y++)
|
||||
{
|
||||
EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
|
||||
}
|
||||
for (y = Dimensions->top; y < Dimensions->bottom; y++)
|
||||
{
|
||||
// EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
|
||||
BRUSHINST *BrushInst, POINTL *BrushPoint)
|
||||
{
|
||||
RECT_ENUM RectEnum;
|
||||
BOOL EnumMore;
|
||||
RECT_ENUM RectEnum;
|
||||
BOOL EnumMore;
|
||||
|
||||
switch(ClipRegion->iMode) {
|
||||
switch(ClipRegion->iMode) {
|
||||
|
||||
case TC_RECTANGLES:
|
||||
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 */
|
||||
/* 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)
|
||||
{
|
||||
FillSolid(Surface, &ClipRegion->rclBounds, iColor);
|
||||
} else {
|
||||
if (ClipRegion->iDComplexity == DC_RECT)
|
||||
{
|
||||
FillSolid(Surface, &ClipRegion->rclBounds, iColor);
|
||||
} else {
|
||||
|
||||
/* Enumerate all the rectangles and draw them */
|
||||
/* Enumerate all the rectangles and draw them */
|
||||
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||
|
||||
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY,
|
||||
ENUM_RECT_LIMIT);
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
|
||||
FillSolid(Surface, &RectEnum.arcl[0], iColor);
|
||||
} while (EnumMore);
|
||||
}
|
||||
|
||||
do {
|
||||
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
|
||||
return(TRUE);
|
||||
|
||||
FillSolid(Surface, &RectEnum.arcl[0], iColor);
|
||||
|
||||
} while (EnumMore);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
||||
default:
|
||||
return(FALSE);
|
||||
}
|
||||
default:
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
|
||||
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
|
||||
IN MIX Mix)
|
||||
{
|
||||
SURFGDI *SurfGDI;
|
||||
SURFGDI *SurfGDI;
|
||||
|
||||
// Is the surface's Paint function hooked?
|
||||
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
||||
// Is the surface's Paint function hooked?
|
||||
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
||||
|
||||
if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
|
||||
{
|
||||
// Call the driver's DrvPaint
|
||||
return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
|
||||
}
|
||||
if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
|
||||
{
|
||||
// Call the driver's DrvPaint
|
||||
return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
|
||||
}
|
||||
|
||||
// FIXME: We only support a brush's solid color attribute
|
||||
return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL,
|
||||
BrushOrigin));
|
||||
// FIXME: We only support a brush's solid color attribute
|
||||
return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin));
|
||||
}
|
||||
|
||||
BOOL EngEraseSurface(SURFOBJ *Surface, RECTL *Rect, ULONG iColor)
|
||||
{
|
||||
return FillSolid(Surface, Rect, iColor);
|
||||
return FillSolid(Surface, Rect, iColor);
|
||||
}
|
||||
|
|
|
@ -18,59 +18,65 @@ HPALETTE EngCreatePalette(ULONG Mode,
|
|||
ULONG Green,
|
||||
ULONG Blue)
|
||||
{
|
||||
HPALETTE NewPalette;
|
||||
PALOBJ *PalObj;
|
||||
PALGDI *PalGDI;
|
||||
HPALETTE NewPalette;
|
||||
PALOBJ *PalObj;
|
||||
PALGDI *PalGDI;
|
||||
|
||||
PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
|
||||
PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL);
|
||||
PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
|
||||
PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL);
|
||||
|
||||
NewPalette = CreateGDIHandle(PalGDI, PalObj);
|
||||
NewPalette = CreateGDIHandle(PalGDI, PalObj);
|
||||
|
||||
PalGDI->Mode = Mode;
|
||||
PalGDI->Mode = Mode;
|
||||
|
||||
if(Mode==PAL_INDEXED)
|
||||
{
|
||||
PalGDI->NumColors = NumColors;
|
||||
PalGDI->IndexedColors = Colors;
|
||||
} else
|
||||
if(Mode==PAL_BITFIELDS)
|
||||
{
|
||||
PalGDI->RedMask = Red;
|
||||
PalGDI->GreenMask = Green;
|
||||
PalGDI->BlueMask = Blue;
|
||||
}
|
||||
if(Colors != NULL)
|
||||
{
|
||||
PalGDI->IndexedColors = ExAllocatePool(NonPagedPool, sizeof(ULONG)*NumColors);
|
||||
RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(ULONG)*NumColors);
|
||||
}
|
||||
|
||||
return NewPalette;
|
||||
if(Mode==PAL_INDEXED)
|
||||
{
|
||||
PalGDI->NumColors = NumColors;
|
||||
PalGDI->IndexedColors = Colors;
|
||||
} else
|
||||
if(Mode==PAL_BITFIELDS)
|
||||
{
|
||||
PalGDI->RedMask = Red;
|
||||
PalGDI->GreenMask = Green;
|
||||
PalGDI->BlueMask = Blue;
|
||||
}
|
||||
|
||||
return NewPalette;
|
||||
}
|
||||
|
||||
BOOL EngDeletePalette(IN HPALETTE Palette)
|
||||
{
|
||||
PALOBJ *PalObj;
|
||||
PALGDI *PalGDI;
|
||||
PALOBJ *PalObj;
|
||||
PALGDI *PalGDI;
|
||||
|
||||
PalGDI = AccessInternalObject(Palette);
|
||||
PalObj = AccessInternalObject(Palette);
|
||||
PalGDI = AccessInternalObject(Palette);
|
||||
PalObj = AccessInternalObject(Palette);
|
||||
|
||||
EngFreeMem(PalGDI);
|
||||
EngFreeMem(PalObj);
|
||||
FreeGDIHandle(Palette);
|
||||
EngFreeMem(PalGDI);
|
||||
EngFreeMem(PalObj);
|
||||
FreeGDIHandle(Palette);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors,
|
||||
ULONG *PaletteEntry)
|
||||
{
|
||||
ULONG i, entry;
|
||||
PALGDI *PalGDI;
|
||||
ULONG i, entry;
|
||||
PALGDI *PalGDI;
|
||||
|
||||
PalGDI = AccessInternalObjectFromUserObject(PalObj);
|
||||
PalGDI = AccessInternalObjectFromUserObject(PalObj);
|
||||
|
||||
for(i=Start; i<Colors; i++)
|
||||
{
|
||||
PaletteEntry[i] = PalGDI->IndexedColors[i];
|
||||
}
|
||||
for(i=Start; i<Colors; i++)
|
||||
{
|
||||
PaletteEntry[i] = PalGDI->IndexedColors[i];
|
||||
}
|
||||
|
||||
return Colors;
|
||||
return Colors;
|
||||
}
|
||||
|
|
|
@ -6,64 +6,72 @@
|
|||
* PROGRAMER: Jason Filby
|
||||
* REVISION HISTORY:
|
||||
* 3/7/1999: Created
|
||||
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
|
||||
* TESTING TO BE DONE:
|
||||
* - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
|
||||
* refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
|
||||
*/
|
||||
|
||||
#include <ddk/winddi.h>
|
||||
#include <win32k/dc.h>
|
||||
#include "objects.h"
|
||||
|
||||
BYTE bytesPerPixel(ULONG Format)
|
||||
INT BitsPerFormat(ULONG Format)
|
||||
{
|
||||
// FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
|
||||
// pixel size if < 1 byte we expand it to 1 byte
|
||||
switch(Format)
|
||||
{
|
||||
case BMF_1BPP: return 1;
|
||||
case BMF_4BPP:
|
||||
case BMF_4RLE: return 4;
|
||||
case BMF_8BPP:
|
||||
case BMF_8RLE: return 8;
|
||||
case BMF_16BPP: return 16;
|
||||
case BMF_24BPP: return 24;
|
||||
case BMF_32BPP: return 32;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
ULONG BitmapFormat(WORD Bits, DWORD Compression)
|
||||
{
|
||||
switch(Compression)
|
||||
{
|
||||
case BI_RGB:
|
||||
switch(Bits)
|
||||
{
|
||||
case 1: return BMF_1BPP;
|
||||
case 4: return BMF_4BPP;
|
||||
case 8: return BMF_8BPP;
|
||||
case 16: return BMF_16BPP;
|
||||
case 24: return BMF_24BPP;
|
||||
case 32: return BMF_32BPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
case BI_RLE4: return BMF_4RLE;
|
||||
case BI_RLE8: return BMF_8RLE;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
VOID InitializeHooks(SURFGDI *SurfGDI)
|
||||
{
|
||||
SurfGDI->BitBlt = NULL;
|
||||
SurfGDI->CopyBits = NULL;
|
||||
SurfGDI->CreateDeviceBitmap = NULL;
|
||||
SurfGDI->BitBlt = NULL;
|
||||
SurfGDI->CopyBits = NULL;
|
||||
SurfGDI->CreateDeviceBitmap = NULL;
|
||||
SurfGDI->SetPalette = NULL;
|
||||
}
|
||||
|
||||
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
||||
{
|
||||
HBITMAP NewBitmap;
|
||||
SURFOBJ *SurfObj;
|
||||
HBITMAP NewBitmap;
|
||||
SURFOBJ *SurfObj;
|
||||
|
||||
NewBitmap = EngCreateBitmap(Size, bytesPerPixel(Format) * Size.cx, Format, 0, NULL);
|
||||
SurfObj = AccessUserObject(NewBitmap);
|
||||
SurfObj->dhpdev = dhsurf;
|
||||
NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
|
||||
SurfObj = (PVOID)AccessUserObject(NewBitmap);
|
||||
SurfObj->dhpdev = dhsurf;
|
||||
|
||||
return NewBitmap;
|
||||
|
||||
return 0;
|
||||
return NewBitmap;
|
||||
}
|
||||
|
||||
HBITMAP EngCreateBitmap(IN SIZEL Size,
|
||||
|
@ -72,141 +80,134 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
|
|||
IN ULONG Flags,
|
||||
IN PVOID Bits)
|
||||
{
|
||||
HBITMAP NewBitmap;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
HBITMAP NewBitmap;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
|
||||
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
|
||||
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
|
||||
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), 0);
|
||||
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), 0);
|
||||
|
||||
NewBitmap = CreateGDIHandle(SurfGDI, SurfObj);
|
||||
NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
|
||||
|
||||
InitializeHooks(SurfGDI);
|
||||
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
|
||||
InitializeHooks(SurfGDI);
|
||||
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
|
||||
SurfObj->lDelta = Width;
|
||||
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
||||
|
||||
SurfObj->lDelta = ((bytesPerPixel(Format) * Width) + 31) & ~31; // round up 4 bytes
|
||||
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
||||
|
||||
if(Bits!=NULL)
|
||||
{
|
||||
SurfObj->pvBits = Bits;
|
||||
} else
|
||||
{
|
||||
if(Flags & BMF_USERMEM)
|
||||
if(Bits!=NULL)
|
||||
{
|
||||
SurfObj->pvBits = Bits;
|
||||
} else
|
||||
{
|
||||
if(Flags & BMF_USERMEM)
|
||||
{
|
||||
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
|
||||
} else {
|
||||
if(Flags & BMF_NOZEROINIT)
|
||||
{
|
||||
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
|
||||
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
|
||||
} else {
|
||||
if(Flags & BMF_NOZEROINIT)
|
||||
{
|
||||
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
|
||||
} else {
|
||||
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
|
||||
}
|
||||
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SurfObj->dhsurf = 0; // device managed surface
|
||||
SurfObj->hsurf = 0;
|
||||
SurfObj->sizlBitmap = Size;
|
||||
SurfObj->iBitmapFormat = Format;
|
||||
SurfObj->iType = STYPE_BITMAP;
|
||||
SurfObj->dhsurf = 0; // device managed surface
|
||||
SurfObj->hsurf = 0;
|
||||
SurfObj->sizlBitmap = Size;
|
||||
SurfObj->iBitmapFormat = Format;
|
||||
SurfObj->iType = STYPE_BITMAP;
|
||||
|
||||
// Use flags to determine bitmap type -- TOP_DOWN or whatever
|
||||
// Use flags to determine bitmap type -- TOP_DOWN or whatever
|
||||
|
||||
return NewBitmap;
|
||||
return NewBitmap;
|
||||
}
|
||||
|
||||
HSURF EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
||||
{
|
||||
HSURF NewSurface;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
HSURF NewSurface;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
|
||||
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
|
||||
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
|
||||
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
|
||||
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
|
||||
|
||||
NewSurface = CreateGDIHandle(SurfGDI, SurfObj);
|
||||
NewSurface = CreateGDIHandle(SurfGDI, SurfObj);
|
||||
|
||||
InitializeHooks(SurfGDI);
|
||||
InitializeHooks(SurfGDI);
|
||||
|
||||
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
|
||||
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
|
||||
SurfObj->dhsurf = dhsurf;
|
||||
SurfObj->hsurf = dhsurf; // FIXME: Is this correct??
|
||||
SurfObj->sizlBitmap = Size;
|
||||
SurfObj->iBitmapFormat = Format;
|
||||
SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
|
||||
SurfObj->iType = STYPE_DEVICE;
|
||||
|
||||
SurfObj->dhsurf = dhsurf;
|
||||
SurfObj->hsurf = dhsurf; // FIXME: Is this correct??
|
||||
SurfObj->sizlBitmap = Size;
|
||||
SurfObj->iBitmapFormat = Format;
|
||||
SurfObj->lDelta = SurfGDI->BytesPerPixel * Size.cx;
|
||||
SurfObj->iType = STYPE_DEVICE;
|
||||
|
||||
return NewSurface;
|
||||
return NewSurface;
|
||||
}
|
||||
|
||||
PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
for(i=0; i<DED->c; i++)
|
||||
{
|
||||
if(DED->pdrvfn[i].iFunc == DriverFunc)
|
||||
return DED->pdrvfn[i].pfn;
|
||||
}
|
||||
return NULL;
|
||||
for(i=0; i<DED->c; i++)
|
||||
{
|
||||
if(DED->pdrvfn[i].iFunc == DriverFunc)
|
||||
return DED->pdrvfn[i].pfn;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
|
||||
{
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
|
||||
// it looks like this Dev is actually a pointer to the DC!
|
||||
PDC Dc = (PDC)Dev;
|
||||
DbgPrint("Associate 1\n");
|
||||
// DRVENABLEDATA *DED;
|
||||
PDC Dc = (PDC)Dev;
|
||||
|
||||
SurfGDI = AccessInternalObject(Surface);
|
||||
SurfObj = AccessUserObject(Surface);
|
||||
SurfGDI = (PVOID)AccessInternalObject(Surface);
|
||||
SurfObj = (PVOID)AccessUserObject(Surface);
|
||||
|
||||
// DED = AccessInternalObject(Dev);
|
||||
// Associate the hdev
|
||||
SurfObj->hdev = Dev;
|
||||
|
||||
// Associate the hdev
|
||||
SurfObj->hdev = Dev;
|
||||
// Hook up specified functions
|
||||
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
|
||||
if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = Dc->DriverFunctions.StretchBlt;
|
||||
if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
|
||||
if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
|
||||
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;
|
||||
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;
|
||||
|
||||
// Hook up specified functions
|
||||
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
|
||||
if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = Dc->DriverFunctions.StretchBlt;
|
||||
if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
|
||||
if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
|
||||
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;
|
||||
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;
|
||||
SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
|
||||
SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
|
||||
|
||||
SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EngDeleteSurface(HSURF Surface)
|
||||
{
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFGDI *SurfGDI;
|
||||
|
||||
SurfGDI = AccessInternalObject(Surface);
|
||||
SurfObj = AccessUserObject(Surface);
|
||||
SurfGDI = AccessInternalObject(Surface);
|
||||
SurfObj = AccessUserObject(Surface);
|
||||
|
||||
EngFreeMem(SurfGDI);
|
||||
EngFreeMem(SurfObj);
|
||||
FreeGDIHandle(Surface);
|
||||
EngFreeMem(SurfGDI);
|
||||
EngFreeMem(SurfObj);
|
||||
FreeGDIHandle(Surface);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SURFOBJ *EngLockSurface(HSURF Surface)
|
||||
{
|
||||
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
|
||||
|
||||
return AccessUserObject(Surface);
|
||||
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
|
||||
return AccessUserObject(Surface);
|
||||
}
|
||||
|
|
|
@ -18,251 +18,249 @@ ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
|
|||
|
||||
ULONG RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue)
|
||||
{
|
||||
return ((Red & 0xff) << 16) | ((Green & 0xff) << 8) | (Blue & 0xff);
|
||||
return ((Red & 0xff) << 16) | ((Green & 0xff) << 8) | (Blue & 0xff);
|
||||
}
|
||||
|
||||
ULONG BGRtoULONG(BYTE Blue, BYTE Green, BYTE Red)
|
||||
{
|
||||
return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff);
|
||||
return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff);
|
||||
}
|
||||
|
||||
INT abs(INT nm)
|
||||
{
|
||||
if(nm<0)
|
||||
{
|
||||
return nm * -1;
|
||||
} else
|
||||
{
|
||||
return nm;
|
||||
}
|
||||
if(nm<0)
|
||||
{
|
||||
return nm * -1;
|
||||
} else
|
||||
{
|
||||
return nm;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: If the caller knows that the destinations are indexed and not RGB
|
||||
// then we should cache more than one value. Same with the source.
|
||||
|
||||
// Takes indexed palette and a
|
||||
ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
||||
ULONG NumColors)
|
||||
{
|
||||
PVIDEO_CLUTDATA cSourceColor;
|
||||
PVIDEO_CLUTDATA cDestColors;
|
||||
ULONG bestMatch = 256, idx = 0, i;
|
||||
ULONG rt;
|
||||
PVIDEO_CLUTDATA cSourceColor;
|
||||
PVIDEO_CLUTDATA cDestColors;
|
||||
ULONG bestMatch = 256, idx = 0, i;
|
||||
ULONG rt;
|
||||
|
||||
// Simple cache -- only one value because we don't want to waste time
|
||||
// if the colors aren't very sequential
|
||||
// Simple cache -- only one value because we don't want to waste time
|
||||
// if the colors aren't very sequential
|
||||
|
||||
if(SourceColor == CCMLastSourceColor)
|
||||
{
|
||||
return CCMLastColorMatch;
|
||||
}
|
||||
if(SourceColor == CCMLastSourceColor)
|
||||
{
|
||||
return CCMLastColorMatch;
|
||||
}
|
||||
|
||||
cSourceColor = &SourceColor;
|
||||
cSourceColor = &SourceColor;
|
||||
|
||||
for (i=0; i<NumColors; i++)
|
||||
{
|
||||
cDestColors = &DestColors[i];
|
||||
for (i=0; i<NumColors; i++)
|
||||
{
|
||||
cDestColors = &DestColors[i];
|
||||
|
||||
rt = ( abs(cSourceColor->Red - cDestColors->Red) +
|
||||
abs(cSourceColor->Green - cDestColors->Green) +
|
||||
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
|
||||
rt = ( abs(cSourceColor->Red - cDestColors->Red) +
|
||||
abs(cSourceColor->Green - cDestColors->Green) +
|
||||
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
|
||||
|
||||
if(rt<=bestMatch)
|
||||
{
|
||||
idx = i;
|
||||
bestMatch = rt;
|
||||
}
|
||||
}
|
||||
if(rt<=bestMatch)
|
||||
{
|
||||
idx = i;
|
||||
bestMatch = rt;
|
||||
}
|
||||
}
|
||||
|
||||
CCMLastSourceColor = SourceColor;
|
||||
CCMLastColorMatch = idx;
|
||||
CCMLastSourceColor = SourceColor;
|
||||
CCMLastColorMatch = idx;
|
||||
|
||||
return idx;
|
||||
return idx;
|
||||
}
|
||||
|
||||
VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
|
||||
PALGDI *PalDest, PALGDI *PalSource)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
for(i=0; i<PalSource->NumColors; i++)
|
||||
{
|
||||
TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i],
|
||||
PalDest->IndexedColors, PalDest->NumColors);
|
||||
}
|
||||
for(i=0; i<PalSource->NumColors; i++)
|
||||
{
|
||||
TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors);
|
||||
}
|
||||
}
|
||||
|
||||
XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
|
||||
HPALETTE PaletteDest, HPALETTE PaletteSource)
|
||||
{
|
||||
// FIXME: Add support for BGR conversions
|
||||
// FIXME: Add support for BGR conversions
|
||||
|
||||
HPALETTE NewXlate;
|
||||
XLATEOBJ *XlateObj;
|
||||
XLATEGDI *XlateGDI;
|
||||
PALGDI *SourcePalGDI, *DestPalGDI;
|
||||
ULONG IndexedColors;
|
||||
HPALETTE NewXlate;
|
||||
XLATEOBJ *XlateObj;
|
||||
XLATEGDI *XlateGDI;
|
||||
PALGDI *SourcePalGDI, *DestPalGDI;
|
||||
ULONG IndexedColors;
|
||||
|
||||
XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
|
||||
XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
|
||||
XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
|
||||
XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
|
||||
|
||||
NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
|
||||
NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
|
||||
|
||||
if(SourcePalType == PAL_INDEXED)
|
||||
{
|
||||
SourcePalGDI = AccessInternalObject(PaletteSource);
|
||||
} else
|
||||
if(DestPalType == PAL_INDEXED)
|
||||
{
|
||||
DestPalGDI = AccessInternalObject(PaletteDest);
|
||||
}
|
||||
if(SourcePalType == PAL_INDEXED)
|
||||
{
|
||||
SourcePalGDI = AccessInternalObject(PaletteSource);
|
||||
} else
|
||||
if(DestPalType == PAL_INDEXED)
|
||||
{
|
||||
DestPalGDI = AccessInternalObject(PaletteDest);
|
||||
}
|
||||
|
||||
XlateObj->iSrcType = SourcePalType;
|
||||
XlateObj->iDstType = DestPalType;
|
||||
XlateObj->iSrcType = SourcePalType;
|
||||
XlateObj->iDstType = DestPalType;
|
||||
|
||||
// Store handles of palettes in internal Xlate GDI object (or NULLs)
|
||||
XlateGDI->DestPal = PaletteDest;
|
||||
XlateGDI->SourcePal = PaletteSource;
|
||||
// Store handles of palettes in internal Xlate GDI object (or NULLs)
|
||||
XlateGDI->DestPal = PaletteDest;
|
||||
XlateGDI->SourcePal = PaletteSource;
|
||||
|
||||
XlateObj->flXlate = 0;
|
||||
XlateObj->flXlate = 0;
|
||||
|
||||
// If source and destination palettes are the same or if they're RGB/BGR
|
||||
if( (PaletteDest == PaletteSource) ||
|
||||
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
|
||||
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
|
||||
{
|
||||
XlateObj->flXlate |= XO_TRIVIAL;
|
||||
}
|
||||
// If source and destination palettes are the same or if they're RGB/BGR
|
||||
if( (PaletteDest == PaletteSource) ||
|
||||
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
|
||||
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
|
||||
{
|
||||
XlateObj->flXlate |= XO_TRIVIAL;
|
||||
return XlateObj;
|
||||
}
|
||||
|
||||
// Prepare the translation table
|
||||
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
||||
{
|
||||
XlateObj->flXlate |= XO_TABLE;
|
||||
// Prepare the translation table
|
||||
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
||||
{
|
||||
XlateObj->flXlate |= XO_TABLE;
|
||||
|
||||
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
|
||||
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
|
||||
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
|
||||
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
|
||||
|
||||
XlateGDI->translationTable = EngAllocMem(
|
||||
FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
|
||||
}
|
||||
XlateGDI->translationTable = EngAllocMem(FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
|
||||
}
|
||||
|
||||
// Source palette is indexed
|
||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||
{
|
||||
if(XlateObj->iDstType == PAL_INDEXED)
|
||||
{
|
||||
// Converting from indexed to indexed
|
||||
IndexedToIndexedTranslationTable(XlateGDI->translationTable,
|
||||
DestPalGDI, SourcePalGDI);
|
||||
} else
|
||||
// Source palette is indexed
|
||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||
{
|
||||
if(XlateObj->iDstType == PAL_INDEXED)
|
||||
{
|
||||
// Converting from indexed to indexed
|
||||
IndexedToIndexedTranslationTable(XlateGDI->translationTable, DestPalGDI, SourcePalGDI);
|
||||
} else
|
||||
if(XlateObj->iDstType == PAL_RGB)
|
||||
{
|
||||
// FIXME: Is this necessary? I think the driver has to call this
|
||||
// function anyways if pulXlate is NULL and Source is PAL_INDEXED
|
||||
// FIXME: Is this necessary? I think the driver has to call this
|
||||
// function anyways if pulXlate is NULL and Source is PAL_INDEXED
|
||||
|
||||
// Converting from indexed to RGB
|
||||
// Converting from indexed to RGB
|
||||
|
||||
XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
|
||||
SourcePalGDI->NumColors,
|
||||
XlateGDI->translationTable);
|
||||
XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
|
||||
SourcePalGDI->NumColors,
|
||||
XlateGDI->translationTable);
|
||||
}
|
||||
|
||||
XlateObj->pulXlate = XlateGDI->translationTable;
|
||||
}
|
||||
XlateObj->pulXlate = XlateGDI->translationTable;
|
||||
}
|
||||
|
||||
// Source palette is RGB
|
||||
if(XlateObj->iSrcType == PAL_RGB)
|
||||
{
|
||||
if(XlateObj->iDstType == PAL_INDEXED)
|
||||
{
|
||||
// FIXME: Is this necessary? I think the driver has to call this
|
||||
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED
|
||||
// Source palette is RGB
|
||||
if(XlateObj->iSrcType == PAL_RGB)
|
||||
{
|
||||
if(XlateObj->iDstType == PAL_INDEXED)
|
||||
{
|
||||
// FIXME: Is this necessary? I think the driver has to call this
|
||||
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED
|
||||
|
||||
// Converting from RGB to indexed
|
||||
XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE,
|
||||
DestPalGDI->NumColors,
|
||||
XlateGDI->translationTable);
|
||||
}
|
||||
}
|
||||
// Converting from RGB to indexed
|
||||
XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE, DestPalGDI->NumColors, XlateGDI->translationTable);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Add support for XO_TO_MONO
|
||||
|
||||
return XlateObj;
|
||||
// FIXME: Add support for XO_TO_MONO
|
||||
return XlateObj;
|
||||
}
|
||||
|
||||
EngDeleteXlate(XLATEOBJ *XlateObj)
|
||||
{
|
||||
HPALETTE HXlate = AccessHandleFromUserObject(XlateObj);
|
||||
XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
|
||||
HPALETTE HXlate = AccessHandleFromUserObject(XlateObj);
|
||||
XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
|
||||
|
||||
if(XlateGDI->translationTable!=NULL)
|
||||
{
|
||||
EngFreeMem(XlateGDI->translationTable);
|
||||
}
|
||||
if(XlateGDI->translationTable!=NULL)
|
||||
{
|
||||
EngFreeMem(XlateGDI->translationTable);
|
||||
}
|
||||
|
||||
EngFreeMem(XlateGDI);
|
||||
EngFreeMem(XlateObj);
|
||||
FreeGDIHandle(HXlate);
|
||||
EngFreeMem(XlateGDI);
|
||||
EngFreeMem(XlateObj);
|
||||
FreeGDIHandle(HXlate);
|
||||
}
|
||||
|
||||
ULONG *XLATEOBJ_piVector(XLATEOBJ *XlateObj)
|
||||
{
|
||||
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||
|
||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||
{
|
||||
return XlateGDI->translationTable;
|
||||
}
|
||||
|
||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||
{
|
||||
return XlateGDI->translationTable;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
|
||||
{
|
||||
PALGDI *PalGDI;
|
||||
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||
PALGDI *PalGDI;
|
||||
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||
|
||||
if(XlateObj->iSrcType == PAL_RGB)
|
||||
{
|
||||
// FIXME: should we cache colors used often?
|
||||
// FIXME: won't work if destination isn't indexed
|
||||
if(XlateObj->flXlate & XO_TRIVIAL)
|
||||
{
|
||||
return Color;
|
||||
} else
|
||||
if(XlateObj->iSrcType == PAL_RGB)
|
||||
{
|
||||
// FIXME: should we cache colors used often?
|
||||
// FIXME: won't work if destination isn't indexed
|
||||
|
||||
// Extract the destination palette
|
||||
PalGDI = AccessInternalObject(XlateGDI->DestPal);
|
||||
// Extract the destination palette
|
||||
PalGDI = AccessInternalObject(XlateGDI->DestPal);
|
||||
|
||||
// Return closest match for the given RGB color
|
||||
return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
|
||||
} else
|
||||
// Return closest match for the given RGB color
|
||||
return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
|
||||
} else
|
||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||
{
|
||||
return XlateGDI->translationTable[Color];
|
||||
}
|
||||
|
||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||
{
|
||||
return XlateGDI->translationTable[Color];
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
|
||||
ULONG PalOutType, ULONG cPal, ULONG *OutPal)
|
||||
{
|
||||
ULONG i;
|
||||
HPALETTE HPal;
|
||||
XLATEGDI *XlateGDI;
|
||||
PALGDI *PalGDI;
|
||||
ULONG i;
|
||||
HPALETTE HPal;
|
||||
XLATEGDI *XlateGDI;
|
||||
PALGDI *PalGDI;
|
||||
|
||||
XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||
XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||
|
||||
if(PalOutType == XO_SRCPALETTE)
|
||||
{
|
||||
HPal = XlateGDI->SourcePal;
|
||||
} else
|
||||
if(PalOutType == XO_DESTPALETTE)
|
||||
{
|
||||
HPal = XlateGDI->DestPal;
|
||||
}
|
||||
if(PalOutType == XO_SRCPALETTE)
|
||||
{
|
||||
HPal = XlateGDI->SourcePal;
|
||||
} else
|
||||
if(PalOutType == XO_DESTPALETTE)
|
||||
{
|
||||
HPal = XlateGDI->DestPal;
|
||||
}
|
||||
|
||||
PalGDI = AccessInternalObject(HPal);
|
||||
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
|
||||
PalGDI = AccessInternalObject(HPal);
|
||||
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
|
||||
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -285,9 +285,11 @@ void CreateCellCharSurface()
|
|||
surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI));
|
||||
|
||||
hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel
|
||||
|
||||
pbo = BITMAPOBJ_HandleToPtr(hCharCellBitmap);
|
||||
|
||||
BitmapToSurf(surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface
|
||||
// VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
|
||||
BitmapToSurf(0, surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface
|
||||
}
|
||||
|
||||
void grWriteCellChar(PSURFOBJ target,
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
/* $Id: loader.c,v 1.5 2000/08/26 16:21:28 ekohl Exp $
|
||||
/* $Id: loader.c,v 1.6 2001/03/31 15:35:07 jfilby Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/winddi.h>
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
EngLoadImage (LPWSTR DriverName)
|
||||
{
|
||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
||||
NTSTATUS Status;
|
||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
||||
DriverName);
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
||||
&GdiDriverInfo,
|
||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status)) return NULL;
|
||||
|
||||
return (HANDLE)GdiDriverInfo.ImageAddress;
|
||||
return (HANDLE)GdiDriverInfo.ImageAddress;
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,20 +24,16 @@ HANDLE
|
|||
STDCALL
|
||||
EngLoadModule(LPWSTR ModuleName)
|
||||
{
|
||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
||||
NTSTATUS Status;
|
||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
||||
NTSTATUS Status;
|
||||
|
||||
// FIXME: should load as readonly
|
||||
// FIXME: should load as readonly
|
||||
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
||||
ModuleName);
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
||||
&GdiDriverInfo,
|
||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName, ModuleName);
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status)) return NULL;
|
||||
|
||||
return (HANDLE)GdiDriverInfo.ImageAddress;
|
||||
return (HANDLE)GdiDriverInfo.ImageAddress;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dllmain.c,v 1.17 2000/09/08 19:39:31 ekohl Exp $
|
||||
/* $Id: dllmain.c,v 1.18 2001/03/31 15:35:08 jfilby Exp $
|
||||
*
|
||||
* Entry Point for win32k.sys
|
||||
*/
|
||||
|
@ -25,31 +25,26 @@
|
|||
NTSTATUS
|
||||
STDCALL
|
||||
DllMain (
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
)
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
BOOLEAN Result;
|
||||
|
||||
DbgPrint("Win32 kernel mode driver\n");
|
||||
DbgPrint("Win32 kernel mode driver\n");
|
||||
|
||||
/*
|
||||
* Register user mode call interface
|
||||
* (system service table index = 1)
|
||||
*/
|
||||
Result = KeAddSystemServiceTable (Win32kSSDT,
|
||||
NULL,
|
||||
NUMBER_OF_SYSCALLS,
|
||||
Win32kSSPT,
|
||||
1);
|
||||
if (Result == FALSE)
|
||||
{
|
||||
DbgPrint("Adding system services failed!\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
/*
|
||||
* Register user mode call interface
|
||||
* (system service table index = 1)
|
||||
*/
|
||||
Result = KeAddSystemServiceTable (Win32kSSDT, NULL, NUMBER_OF_SYSCALLS, Win32kSSPT, 1);
|
||||
if (Result == FALSE)
|
||||
{
|
||||
DbgPrint("Adding system services failed!\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DbgPrint("System services added successfully!\n");
|
||||
return STATUS_SUCCESS;
|
||||
DbgPrint("System services added successfully!\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,14 +52,19 @@ BOOLEAN
|
|||
STDCALL
|
||||
W32kInitialize (VOID)
|
||||
{
|
||||
// FIXME: Retrieve name from registry
|
||||
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
||||
|
||||
// FIXME: Retrieve name from registry
|
||||
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
||||
// Create surface used to draw the internal font onto
|
||||
CreateCellCharSurface();
|
||||
|
||||
// Create surface used to draw the internal font onto
|
||||
CreateCellCharSurface();
|
||||
// Create stock objects, ie. precreated objects commonly used by win32 applications
|
||||
CreateStockObjects();
|
||||
|
||||
return TRUE;
|
||||
// Initialize FreeType library
|
||||
if(!InitFontSupport()) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.27 2000/11/20 19:59:14 ekohl Exp $
|
||||
# $Id: makefile,v 1.28 2001/03/31 15:35:07 jfilby Exp $
|
||||
#
|
||||
# WIN32K.SYS build spec
|
||||
#
|
||||
|
@ -6,8 +6,13 @@ PATH_TO_TOP = ../..
|
|||
|
||||
TARGET=win32k
|
||||
|
||||
# from atheos appserver makefile
|
||||
COPTS = -pipe -O3 -I./freetype2-beta8/include -c -Wall
|
||||
|
||||
CFLAGS = -I.
|
||||
|
||||
#define FT_FLAT_COMPILE
|
||||
|
||||
ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o eng/copybits.o \
|
||||
eng/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
|
||||
eng/surface.o eng/xlate.o
|
||||
|
@ -20,14 +25,19 @@ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
|
|||
objects/line.o objects/metafile.o objects/paint.o \
|
||||
objects/path.o objects/pen.o objects/print.o \
|
||||
objects/region.o objects/text.o objects/wingl.o \
|
||||
objects/bezier.o objects/objconv.o
|
||||
FREETYPE_OBJECTS = freetype/grfont.o
|
||||
|
||||
objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
|
||||
DIB_OBJECTS = dib/dib4bpp.o dib/dib24bpp.o
|
||||
FREETYPE_OBJECTS = freetype/grfont.o freetype/ctype.o \
|
||||
freetype/ftsystem.o freetype/ftdebug.o freetype/ftinit.o freetype/ftbase.o \
|
||||
freetype/ftglyph.o freetype/ftmm.o freetype/autohint.o freetype/cff.o \
|
||||
freetype/type1cid.o freetype/psnames.o freetype/raster1.o freetype/sfnt.o \
|
||||
freetype/smooth.o freetype/truetype.o freetype/winfnt.o freetype/type1z.o
|
||||
RESOURCE_OBJECT = $(TARGET).coff
|
||||
STUBS_OBJECTS = stubs/stubs.o
|
||||
|
||||
OBJECTS = $(ENG_OBJECTS) $(MAIN_OBJECTS) $(MISC_OBJECTS) $(LDR_OBJECTS) $(OBJECTS_OBJECTS) \
|
||||
$(RESOURCE_OBJECT) $(STUBS_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS)
|
||||
$(RESOURCE_OBJECT) $(STUBS_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS) \
|
||||
$(DIB_OBJECTS)
|
||||
|
||||
all: $(TARGET).sys
|
||||
|
||||
|
@ -116,4 +126,3 @@ $(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
|||
#WIN32_LEAN_AND_MEAN = yes
|
||||
#WARNINGS_ARE_ERRORS = yes
|
||||
include ../../rules.mak
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: driver.c,v 1.15 2000/08/26 16:22:04 ekohl Exp $
|
||||
/* $Id: driver.c,v 1.16 2001/03/31 15:35:08 jfilby Exp $
|
||||
*
|
||||
* GDI Driver support routines
|
||||
* (mostly swiped from Wine)
|
||||
|
@ -34,28 +34,23 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
|
|||
{
|
||||
PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver));
|
||||
DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
|
||||
if (!Driver)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!Driver) return FALSE;
|
||||
Driver->ReferenceCount = 0;
|
||||
Driver->EnableDriver = EnableDriver;
|
||||
if (Name)
|
||||
{
|
||||
Driver->Name = ExAllocatePool(PagedPool,
|
||||
(wcslen(Name) + 1) * sizeof(WCHAR));
|
||||
wcscpy(Driver->Name, Name);
|
||||
Driver->Next = DriverList;
|
||||
DriverList = Driver;
|
||||
return TRUE;
|
||||
}
|
||||
{
|
||||
Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR));
|
||||
wcscpy(Driver->Name, Name);
|
||||
Driver->Next = DriverList;
|
||||
DriverList = Driver;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (GenericDriver != NULL)
|
||||
{
|
||||
ExFreePool(Driver);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
ExFreePool(Driver);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GenericDriver = Driver;
|
||||
return TRUE;
|
||||
|
@ -69,22 +64,18 @@ PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
|
|||
|
||||
/* First see if the driver hasn't already been loaded */
|
||||
while (Driver && Name)
|
||||
{
|
||||
if (!_wcsicmp( Driver->Name, Name))
|
||||
{
|
||||
if (!_wcsicmp( Driver->Name, Name))
|
||||
{
|
||||
return Driver->EnableDriver;
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
return Driver->EnableDriver;
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
}
|
||||
|
||||
/* If not, then load it */
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
||||
(LPWSTR)Name);
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
||||
&GdiDriverInfo,
|
||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName, (LPWSTR)Name);
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status)) return NULL;
|
||||
|
||||
DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
|
||||
return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
|
||||
|
@ -182,35 +173,31 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
|
|||
PMP_DRIVERENTRY PMP_DriverEntry;
|
||||
|
||||
/* Phase 1 */
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
||||
L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
||||
&GdiDriverInfo,
|
||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName, L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
|
||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
|
||||
/* Phase 2 */
|
||||
if (Name[0] != '\\')
|
||||
{
|
||||
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) + 10 * sizeof(WCHAR));
|
||||
wcscpy(lName, L"\\??\\");
|
||||
if (!wcscmp (Name, L"DISPLAY"))
|
||||
{
|
||||
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) +
|
||||
10 * sizeof(WCHAR));
|
||||
wcscpy(lName, L"\\??\\");
|
||||
if (!wcscmp (Name, L"DISPLAY"))
|
||||
{
|
||||
/* FIXME: Read this information from the registry ??? */
|
||||
wcscat(lName, L"DISPLAY1");
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat(lName, Name);
|
||||
}
|
||||
/* FIXME: Read this information from the registry ??? */
|
||||
wcscat(lName, L"DISPLAY1");
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscat(lName, Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
|
||||
wcscpy(lName, Name);
|
||||
}
|
||||
{
|
||||
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
|
||||
wcscpy(lName, Name);
|
||||
}
|
||||
|
||||
/* Phase 3 */
|
||||
DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
|
||||
|
@ -234,44 +221,44 @@ BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
|
|||
PGRAPHICS_DRIVER Driver = NULL;
|
||||
|
||||
if (Name)
|
||||
{
|
||||
if (DriverList != NULL)
|
||||
{
|
||||
if (DriverList != NULL)
|
||||
if (!_wcsicmp(DriverList->Name, Name))
|
||||
{
|
||||
Driver = DriverList;
|
||||
DriverList = DriverList->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
Driver = DriverList;
|
||||
while (Driver->Next && _wcsicmp(Driver->Name, Name))
|
||||
{
|
||||
if (!_wcsicmp(DriverList->Name, Name))
|
||||
{
|
||||
Driver = DriverList;
|
||||
DriverList = DriverList->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
Driver = DriverList;
|
||||
while (Driver->Next && _wcsicmp(Driver->Name, Name))
|
||||
{
|
||||
Driver = Driver->Next;
|
||||
}
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GenericDriver != NULL)
|
||||
{
|
||||
Driver = GenericDriver;
|
||||
GenericDriver = NULL;
|
||||
}
|
||||
{
|
||||
if (GenericDriver != NULL)
|
||||
{
|
||||
Driver = GenericDriver;
|
||||
GenericDriver = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (Driver != NULL)
|
||||
{
|
||||
ExFreePool(Driver->Name);
|
||||
ExFreePool(Driver);
|
||||
{
|
||||
ExFreePool(Driver->Name);
|
||||
ExFreePool(Driver);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
INT DRIVER_ReferenceDriver (LPCWSTR Name)
|
||||
|
@ -279,14 +266,14 @@ INT DRIVER_ReferenceDriver (LPCWSTR Name)
|
|||
GRAPHICS_DRIVER *Driver = DriverList;
|
||||
|
||||
while (Driver && Name)
|
||||
{
|
||||
DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
|
||||
if (!_wcsicmp( Driver->Name, Name))
|
||||
{
|
||||
DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
|
||||
if (!_wcsicmp( Driver->Name, Name))
|
||||
{
|
||||
return ++Driver->ReferenceCount;
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
return ++Driver->ReferenceCount;
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
}
|
||||
DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
||||
assert( GenericDriver != 0 );
|
||||
return ++GenericDriver->ReferenceCount;
|
||||
|
@ -297,14 +284,14 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name)
|
|||
GRAPHICS_DRIVER *Driver = DriverList;
|
||||
|
||||
while (Driver && Name)
|
||||
{
|
||||
DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
|
||||
if (!_wcsicmp( Driver->Name, Name))
|
||||
{
|
||||
DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
|
||||
if (!_wcsicmp( Driver->Name, Name))
|
||||
{
|
||||
return --Driver->ReferenceCount;
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
return --Driver->ReferenceCount;
|
||||
}
|
||||
Driver = Driver->Next;
|
||||
}
|
||||
DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
||||
assert( GenericDriver != 0 );
|
||||
return --GenericDriver->ReferenceCount;
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
* */
|
||||
|
||||
#define BEZIERMIDDLE(Mid, P1, P2) \
|
||||
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
||||
(Mid).y=((P1).y+(P2).y + 1)/2;
|
||||
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
||||
(Mid).y=((P1).y+(P2).y + 1)/2;
|
||||
|
||||
/**********************************************************
|
||||
* BezierCheck helper function to check
|
||||
|
@ -54,55 +54,46 @@
|
|||
*/
|
||||
static BOOL BezierCheck( int level, POINT *Points)
|
||||
{
|
||||
INT dx, dy;
|
||||
dx=Points[3].x-Points[0].x;
|
||||
dy=Points[3].y-Points[0].y;
|
||||
if(abs(dy)<=abs(dx)){/* shallow line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].x < Points[0].x){
|
||||
if(Points[1].x < Points[3].x)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[1].x > Points[3].x)
|
||||
return FALSE;
|
||||
if(Points[2].x < Points[0].x){
|
||||
if(Points[2].x < Points[3].x)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[2].x > Points[3].x)
|
||||
return FALSE;
|
||||
dx=BEZIERSHIFTDOWN(dx);
|
||||
if(!dx) return TRUE;
|
||||
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
||||
abs(Points[2].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}else{ /* steep line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].y < Points[0].y){
|
||||
if(Points[1].y < Points[3].y)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[1].y > Points[3].y)
|
||||
return FALSE;
|
||||
if(Points[2].y < Points[0].y){
|
||||
if(Points[2].y < Points[3].y)
|
||||
return FALSE;
|
||||
}else
|
||||
if(Points[2].y > Points[3].y)
|
||||
return FALSE;
|
||||
dy=BEZIERSHIFTDOWN(dy);
|
||||
if(!dy) return TRUE;
|
||||
if(abs(Points[1].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
||||
abs(Points[2].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
INT dx, dy;
|
||||
|
||||
dx=Points[3].x-Points[0].x;
|
||||
dy=Points[3].y-Points[0].y;
|
||||
if(abs(dy)<=abs(dx)) {/* shallow line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].x < Points[0].x){
|
||||
if(Points[1].x < Points[3].x) return FALSE;
|
||||
}else
|
||||
if(Points[1].x > Points[3].x) return FALSE;
|
||||
if(Points[2].x < Points[0].x) {
|
||||
if(Points[2].x < Points[3].x) return FALSE;
|
||||
} else
|
||||
if(Points[2].x > Points[3].x) return FALSE;
|
||||
dx=BEZIERSHIFTDOWN(dx);
|
||||
if(!dx) return TRUE;
|
||||
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
||||
abs(Points[2].y-Points[0].y-(dy/dx)*
|
||||
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL) return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
} else{ /* steep line */
|
||||
/* check that control points are between begin and end */
|
||||
if(Points[1].y < Points[0].y){
|
||||
if(Points[1].y < Points[3].y) return FALSE;
|
||||
} else
|
||||
if(Points[1].y > Points[3].y) return FALSE;
|
||||
if(Points[2].y < Points[0].y){
|
||||
if(Points[2].y < Points[3].y) return FALSE;
|
||||
} else
|
||||
if(Points[2].y > Points[3].y) return FALSE;
|
||||
dy=BEZIERSHIFTDOWN(dy);
|
||||
if(!dy) return TRUE;
|
||||
if(abs(Points[1].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
||||
abs(Points[2].x-Points[0].x-(dx/dy)*
|
||||
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL ) return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,37 +103,37 @@ static BOOL BezierCheck( int level, POINT *Points)
|
|||
static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
|
||||
INT *nPtsOut, INT level )
|
||||
{
|
||||
if(*nPtsOut == *dwOut) {
|
||||
*dwOut *= 2;
|
||||
*PtsOut = ExAllocatePool(NonPagedPool, *dwOut * sizeof(POINT));
|
||||
if(*nPtsOut == *dwOut) {
|
||||
*dwOut *= 2;
|
||||
*PtsOut = ExAllocatePool(NonPagedPool, *dwOut * sizeof(POINT));
|
||||
}
|
||||
|
||||
if(!level || BezierCheck(level, Points)) {
|
||||
if(*nPtsOut == 0) {
|
||||
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
|
||||
(*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
|
||||
*nPtsOut = 1;
|
||||
}
|
||||
(*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
|
||||
(*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
|
||||
(*nPtsOut) ++;
|
||||
} else {
|
||||
POINT Points2[4]; /* for the second recursive call */
|
||||
Points2[3]=Points[3];
|
||||
BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
|
||||
BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
|
||||
BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
|
||||
|
||||
if(!level || BezierCheck(level, Points)) {
|
||||
if(*nPtsOut == 0) {
|
||||
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
|
||||
(*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
|
||||
*nPtsOut = 1;
|
||||
}
|
||||
(*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
|
||||
(*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
|
||||
(*nPtsOut) ++;
|
||||
} else {
|
||||
POINT Points2[4]; /* for the second recursive call */
|
||||
Points2[3]=Points[3];
|
||||
BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
|
||||
BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
|
||||
BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
|
||||
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
||||
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
||||
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
||||
|
||||
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
||||
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
||||
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
||||
Points2[0]=Points[3];
|
||||
|
||||
Points2[0]=Points[3];
|
||||
|
||||
/* do the two halves */
|
||||
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
|
||||
GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
|
||||
}
|
||||
/* do the two halves */
|
||||
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
|
||||
GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -171,23 +162,23 @@ static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
|
|||
*/
|
||||
POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
|
||||
{
|
||||
POINT *out;
|
||||
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
||||
POINT *out;
|
||||
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
||||
|
||||
if((count - 1) % 3 != 0) {
|
||||
return NULL;
|
||||
}
|
||||
*nPtsOut = 0;
|
||||
out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
|
||||
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
||||
POINT ptBuf[4];
|
||||
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
||||
for(i = 0; i < 4; i++) {
|
||||
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
||||
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
||||
}
|
||||
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
||||
if((count - 1) % 3 != 0) {
|
||||
return NULL;
|
||||
}
|
||||
*nPtsOut = 0;
|
||||
out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
|
||||
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
||||
POINT ptBuf[4];
|
||||
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
||||
for(i = 0; i < 4; i++) {
|
||||
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
||||
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
||||
}
|
||||
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
||||
}
|
||||
|
||||
return out;
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <win32k/bitmaps.h>
|
||||
//#include <win32k/debug.h>
|
||||
#include "../eng/objects.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -19,15 +18,19 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
|
|||
INT YSrc,
|
||||
DWORD ROP)
|
||||
{
|
||||
PDC DCDest = DC_HandleToPtr(hDCDest);
|
||||
PDC DCSrc = DC_HandleToPtr(hDCSrc);
|
||||
PSURFOBJ SurfDest;
|
||||
PSURFOBJ SurfSrc;
|
||||
RECTL DestRect;
|
||||
POINTL SourcePoint;
|
||||
PBITMAPOBJ DestBitmapObj;
|
||||
PBITMAPOBJ SrcBitmapObj;
|
||||
BOOL Status, SurfDestAlloc, SurfSrcAlloc;
|
||||
PDC DCDest = DC_HandleToPtr(hDCDest);
|
||||
PDC DCSrc = DC_HandleToPtr(hDCSrc);
|
||||
PSURFOBJ SurfDest, SurfSrc;
|
||||
PSURFGDI SurfGDIDest, SurfGDISrc;
|
||||
RECTL DestRect;
|
||||
POINTL SourcePoint;
|
||||
PBITMAPOBJ DestBitmapObj;
|
||||
PBITMAPOBJ SrcBitmapObj;
|
||||
BOOL Status, SurfDestAlloc, SurfSrcAlloc;
|
||||
PPALOBJ DCLogPal;
|
||||
PPALGDI PalDestGDI, PalSourceGDI;
|
||||
PXLATEOBJ XlateObj = NULL;
|
||||
HPALETTE SourcePalette, DestPalette;
|
||||
|
||||
DestRect.left = XDest;
|
||||
DestRect.top = YDest;
|
||||
|
@ -40,32 +43,44 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
|
|||
SurfDestAlloc = FALSE;
|
||||
SurfSrcAlloc = FALSE;
|
||||
|
||||
DPRINT("Get surfdest.. ");
|
||||
// Determine surfaces to be used in the bitblt
|
||||
SurfDest = AccessUserObject(DCDest->Surface);
|
||||
SurfSrc = AccessUserObject(DCSrc->Surface);
|
||||
|
||||
// Get the SurfDest
|
||||
if(DCDest->Surface != NULL)
|
||||
SurfGDIDest = AccessInternalObjectFromUserObject(SurfDest);
|
||||
SurfGDISrc = AccessInternalObjectFromUserObject(SurfSrc);
|
||||
|
||||
// Retrieve the logical palette of the destination DC
|
||||
DCLogPal = AccessUserObject(DCDest->w.hPalette);
|
||||
|
||||
if(DCLogPal)
|
||||
if(DCLogPal->logicalToSystem)
|
||||
XlateObj = DCLogPal->logicalToSystem;
|
||||
|
||||
// If the source and destination formats differ, create an XlateObj [what if we already have one??]
|
||||
if((BitsPerFormat(SurfDest->iBitmapFormat) != BitsPerFormat(SurfSrc->iBitmapFormat)) && (XlateObj == NULL))
|
||||
{
|
||||
// Use the DC's surface if it has one
|
||||
SurfDest = AccessUserObject(DCDest->Surface);
|
||||
} else
|
||||
return FALSE;
|
||||
if(DCDest->w.hPalette != 0)
|
||||
{
|
||||
DestPalette = DCDest->w.hPalette;
|
||||
} else
|
||||
DestPalette = W32kGetStockObject(DEFAULT_PALETTE);
|
||||
|
||||
DPRINT("Get surfsrc.. ");
|
||||
if(DCSrc->w.hPalette != 0)
|
||||
{
|
||||
SourcePalette = DCSrc->w.hPalette;
|
||||
} else
|
||||
SourcePalette = W32kGetStockObject(DEFAULT_PALETTE);
|
||||
|
||||
// Get the SurfSrc
|
||||
if(DCSrc->Surface != NULL)
|
||||
{
|
||||
DPRINT("from DC's surface\n");
|
||||
PalDestGDI = AccessInternalObject(DestPalette);
|
||||
PalSourceGDI = AccessInternalObject(SourcePalette);
|
||||
|
||||
// Use the DC's surface if it has one
|
||||
SurfSrc = AccessUserObject(DCSrc->Surface);
|
||||
} else
|
||||
return FALSE;
|
||||
XlateObj = EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette);
|
||||
}
|
||||
|
||||
// Perform the bitblt operation
|
||||
|
||||
DPRINT("Go to EngBitBlt\n");
|
||||
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL,
|
||||
&DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
|
||||
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
|
||||
|
||||
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
|
||||
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
|
||||
|
@ -87,35 +102,35 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
|
|||
|
||||
/* Check parameters */
|
||||
if (!Height || !Width)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (Planes != 1)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
if (Height < 0)
|
||||
{
|
||||
Height = -Height;
|
||||
}
|
||||
{
|
||||
Height = -Height;
|
||||
}
|
||||
if (Width < 0)
|
||||
{
|
||||
Width = -Width;
|
||||
}
|
||||
{
|
||||
Width = -Width;
|
||||
}
|
||||
|
||||
/* Create the BITMAPOBJ */
|
||||
bmp = BITMAPOBJ_AllocBitmap ();
|
||||
if (!bmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
|
||||
1 << (Planes * BitsPerPel), BitsPerPel, bmp);
|
||||
|
||||
bmp->size.cx = 0;
|
||||
bmp->size.cy = 0;
|
||||
bmp->size.cx = Width;
|
||||
bmp->size.cy = Height;
|
||||
bmp->bitmap.bmType = 0;
|
||||
bmp->bitmap.bmWidth = Width;
|
||||
bmp->bitmap.bmHeight = Height;
|
||||
|
@ -131,12 +146,9 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
|
|||
bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
|
||||
|
||||
if (Bits) /* Set bitmap bits */
|
||||
{
|
||||
W32kSetBitmapBits(hBitmap,
|
||||
Height * bmp->bitmap.bmWidthBytes,
|
||||
Bits);
|
||||
}
|
||||
|
||||
{
|
||||
W32kSetBitmapBits(hBitmap, Height * bmp->bitmap.bmWidthBytes, Bits);
|
||||
}
|
||||
|
||||
return hBitmap;
|
||||
}
|
||||
|
@ -151,36 +163,31 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
|
|||
hbmpRet = 0;
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
|
||||
DPRINT("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
|
||||
DbgPrint("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
|
||||
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((Width >= 0x10000) || (Height >= 0x10000))
|
||||
{
|
||||
DPRINT("got bad width %d or height %d, please look for reason\n",
|
||||
Width, Height);
|
||||
}
|
||||
{
|
||||
DPRINT("got bad width %d or height %d, please look for reason\n", Width, Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
|
||||
if (!Width || !Height)
|
||||
{
|
||||
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
|
||||
if (!Width || !Height)
|
||||
{
|
||||
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
hbmpRet = W32kCreateBitmap (Width,
|
||||
Height,
|
||||
1,
|
||||
dc->w.bitsPerPixel,
|
||||
NULL);
|
||||
}
|
||||
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
hbmpRet = W32kCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
|
||||
}
|
||||
}
|
||||
DPRINT ("\t\t%04x\n", hbmpRet);
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
|
||||
return hbmpRet;
|
||||
}
|
||||
|
||||
|
@ -193,26 +200,6 @@ HBITMAP STDCALL W32kCreateBitmapIndirect(CONST BITMAP *BM)
|
|||
BM->bmBits);
|
||||
}
|
||||
|
||||
HBITMAP STDCALL W32kCreateDIBitmap(HDC hDC,
|
||||
CONST BITMAPINFOHEADER *bmih,
|
||||
DWORD Init,
|
||||
CONST VOID *bInit,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT Usage)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT Usage,
|
||||
VOID *Bits,
|
||||
HANDLE hSection,
|
||||
DWORD dwOffset)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
HBITMAP STDCALL W32kCreateDiscardableBitmap(HDC hDC,
|
||||
INT Width,
|
||||
INT Height)
|
||||
|
@ -238,83 +225,6 @@ BOOL STDCALL W32kFloodFill(HDC hDC,
|
|||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
|
||||
LONG Count,
|
||||
LPVOID Bits)
|
||||
{
|
||||
PBITMAPOBJ bmp;
|
||||
LONG height, ret;
|
||||
|
||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||
if (!bmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the bits vector is null, the function should return the read size */
|
||||
if (Bits == NULL)
|
||||
{
|
||||
return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
|
||||
}
|
||||
|
||||
if (Count < 0)
|
||||
{
|
||||
DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
|
||||
Count = -Count;
|
||||
}
|
||||
|
||||
/* Only get entire lines */
|
||||
height = Count / bmp->bitmap.bmWidthBytes;
|
||||
if (height > bmp->bitmap.bmHeight)
|
||||
{
|
||||
height = bmp->bitmap.bmHeight;
|
||||
}
|
||||
Count = height * bmp->bitmap.bmWidthBytes;
|
||||
if (Count == 0)
|
||||
{
|
||||
DPRINT("Less then one entire line requested\n");
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
|
||||
hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
|
||||
1 << bmp->bitmap.bmBitsPixel, height );
|
||||
#if 0
|
||||
/* FIXME: Call DDI CopyBits here if available */
|
||||
if(bmp->DDBitmap)
|
||||
{
|
||||
DPRINT("Calling device specific BitmapBits\n");
|
||||
if(bmp->DDBitmap->funcs->pBitmapBits)
|
||||
{
|
||||
ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
|
||||
DDB_GET);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR_(bitmap)("BitmapBits == NULL??\n");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(!bmp->bitmap.bmBits)
|
||||
{
|
||||
DPRINT ("Bitmap is empty\n");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(Bits, bmp->bitmap.bmBits, Count);
|
||||
ret = Count;
|
||||
}
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
||||
LPSIZE Dimension)
|
||||
{
|
||||
|
@ -322,9 +232,9 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
|||
|
||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||
if (bmp == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*Dimension = bmp->size;
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
@ -332,25 +242,6 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
UINT STDCALL W32kGetDIBColorTable(HDC hDC,
|
||||
UINT StartIndex,
|
||||
UINT Entries,
|
||||
RGBQUAD *Colors)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
INT STDCALL W32kGetDIBits(HDC hDC,
|
||||
HBITMAP hBitmap,
|
||||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
LPVOID Bits,
|
||||
LPBITMAPINFO bi,
|
||||
UINT Usage)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
COLORREF STDCALL W32kGetPixel(HDC hDC,
|
||||
INT XPos,
|
||||
INT YPos)
|
||||
|
@ -397,22 +288,22 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
|
|||
|
||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||
if (bmp == NULL || Bits == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Bytes < 0)
|
||||
{
|
||||
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
|
||||
Bytes = -Bytes;
|
||||
}
|
||||
{
|
||||
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
|
||||
Bytes = -Bytes;
|
||||
}
|
||||
|
||||
/* Only get entire lines */
|
||||
height = Bytes / bmp->bitmap.bmWidthBytes;
|
||||
if (height > bmp->bitmap.bmHeight)
|
||||
{
|
||||
height = bmp->bitmap.bmHeight;
|
||||
}
|
||||
{
|
||||
height = bmp->bitmap.bmHeight;
|
||||
}
|
||||
Bytes = height * bmp->bitmap.bmWidthBytes;
|
||||
DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
|
||||
hBitmap,
|
||||
|
@ -426,39 +317,36 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
|
|||
#if 0
|
||||
/* FIXME: call DDI specific function here if available */
|
||||
if(bmp->DDBitmap)
|
||||
{
|
||||
DPRINT ("Calling device specific BitmapBits\n");
|
||||
if (bmp->DDBitmap->funcs->pBitmapBits)
|
||||
{
|
||||
DPRINT ("Calling device specific BitmapBits\n");
|
||||
if (bmp->DDBitmap->funcs->pBitmapBits)
|
||||
{
|
||||
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap,
|
||||
(void *) Bits,
|
||||
Bytes,
|
||||
DDB_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT ("BitmapBits == NULL??\n");
|
||||
ret = 0;
|
||||
}
|
||||
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT ("BitmapBits == NULL??\n");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* FIXME: Alloc enough for entire bitmap */
|
||||
if (bmp->bitmap.bmBits == NULL)
|
||||
{
|
||||
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
|
||||
}
|
||||
{
|
||||
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
|
||||
}
|
||||
if(!bmp->bitmap.bmBits)
|
||||
{
|
||||
DPRINT ("Unable to allocate bit buffer\n");
|
||||
ret = 0;
|
||||
}
|
||||
{
|
||||
DPRINT ("Unable to allocate bit buffer\n");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(bmp->bitmap.bmBits, Bits, Bytes);
|
||||
ret = Bytes;
|
||||
}
|
||||
{
|
||||
memcpy(bmp->bitmap.bmBits, Bits, Bytes);
|
||||
ret = Bytes;
|
||||
}
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
|
@ -474,14 +362,14 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
|
|||
|
||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||
if (bmp == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Size)
|
||||
{
|
||||
*Size = bmp->size;
|
||||
}
|
||||
{
|
||||
*Size = bmp->size;
|
||||
}
|
||||
bmp->size.cx = Width;
|
||||
bmp->size.cy = Height;
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
@ -489,41 +377,6 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
UINT STDCALL W32kSetDIBColorTable(HDC hDC,
|
||||
UINT StartIndex,
|
||||
UINT Entries,
|
||||
CONST RGBQUAD *Colors)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
INT STDCALL W32kSetDIBits(HDC hDC,
|
||||
HBITMAP hBitmap,
|
||||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT ColorUse)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
INT STDCALL W32kSetDIBitsToDevice(HDC hDC,
|
||||
INT XDest,
|
||||
INT YDest,
|
||||
DWORD Width,
|
||||
DWORD Height,
|
||||
INT XSrc,
|
||||
INT YSrc,
|
||||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT ColorUse)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
COLORREF STDCALL W32kSetPixel(HDC hDC,
|
||||
INT X,
|
||||
INT Y,
|
||||
|
@ -555,30 +408,13 @@ BOOL STDCALL W32kStretchBlt(HDC hDCDest,
|
|||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
INT STDCALL W32kStretchDIBits(HDC hDC,
|
||||
INT XDest,
|
||||
INT YDest,
|
||||
INT DestWidth,
|
||||
INT DestHeight,
|
||||
INT XSrc,
|
||||
INT YSrc,
|
||||
INT SrcWidth,
|
||||
INT SrcHeight,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPINFO *BitsInfo,
|
||||
UINT Usage,
|
||||
DWORD ROP)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Internal Functions */
|
||||
|
||||
INT
|
||||
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
|
||||
{
|
||||
switch(bpp)
|
||||
{
|
||||
{
|
||||
case 1:
|
||||
return 2 * ((bmWidth+15) >> 4);
|
||||
|
||||
|
@ -599,7 +435,7 @@ BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
|
|||
|
||||
default:
|
||||
DPRINT ("stub");
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -612,94 +448,47 @@ HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
|
|||
|
||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||
if (bmp == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
res = 0;
|
||||
|
||||
bm = bmp->bitmap;
|
||||
bm.bmBits = NULL;
|
||||
res = W32kCreateBitmapIndirect(&bm);
|
||||
if(res)
|
||||
{
|
||||
char *buf;
|
||||
{
|
||||
char *buf;
|
||||
|
||||
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
|
||||
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
ExFreePool (buf);
|
||||
}
|
||||
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
|
||||
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
ExFreePool (buf);
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetDIBWidthBytes
|
||||
*
|
||||
* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
|
||||
* http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
|
||||
* 11/16/1999 (RJJ) lifted from wine
|
||||
*/
|
||||
int DIB_GetDIBWidthBytes(int width, int depth)
|
||||
INT BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer)
|
||||
{
|
||||
int words;
|
||||
|
||||
switch(depth)
|
||||
if(bmp->dib)
|
||||
{
|
||||
if(count < sizeof(DIBSECTION))
|
||||
{
|
||||
case 1: words = (width + 31) / 32; break;
|
||||
case 4: words = (width + 7) / 8; break;
|
||||
case 8: words = (width + 3) / 4; break;
|
||||
case 15:
|
||||
case 16: words = (width + 1) / 2; break;
|
||||
case 24: words = (width * 3 + 3)/4; break;
|
||||
|
||||
default:
|
||||
DPRINT("(%d): Unsupported depth\n", depth );
|
||||
/* fall through */
|
||||
case 32:
|
||||
words = width;
|
||||
if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
|
||||
}
|
||||
return 4 * words;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetDIBImageBytes
|
||||
*
|
||||
* Return the number of bytes used to hold the image in a DIB bitmap.
|
||||
* 11/16/1999 (RJJ) lifted from wine
|
||||
*/
|
||||
|
||||
int DIB_GetDIBImageBytes (int width, int height, int depth)
|
||||
{
|
||||
return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_BitmapInfoSize
|
||||
*
|
||||
* Return the size of the bitmap info structure including color table.
|
||||
* 11/16/1999 (RJJ) lifted from wine
|
||||
*/
|
||||
|
||||
int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
|
||||
{
|
||||
int colors;
|
||||
|
||||
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
else
|
||||
{
|
||||
BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
|
||||
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
|
||||
return sizeof(BITMAPCOREHEADER) + colors *
|
||||
((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
|
||||
}
|
||||
else /* assume BITMAPINFOHEADER */
|
||||
{
|
||||
colors = info->bmiHeader.biClrUsed;
|
||||
if (!colors && (info->bmiHeader.biBitCount <= 8))
|
||||
colors = 1 << info->bmiHeader.biBitCount;
|
||||
return sizeof(BITMAPINFOHEADER) + colors *
|
||||
((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
|
||||
if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);
|
||||
}
|
||||
memcpy(buffer, bmp->dib, count);
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
|
||||
memcpy(buffer, &bmp->bitmap, count);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: brush.c,v 1.10 2000/06/29 23:35:53 dwelch Exp $
|
||||
/* $Id: brush.c,v 1.11 2001/03/31 15:35:08 jfilby Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -17,16 +17,17 @@ HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH *lb)
|
|||
PBRUSHOBJ brushPtr;
|
||||
HBRUSH hBrush;
|
||||
|
||||
hBrush = BRUSHOBJ_AllocBrush ();
|
||||
brushPtr = BRUSHOBJ_AllocBrush();
|
||||
hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
|
||||
if (hBrush == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
brushPtr = BRUSHOBJ_HandleToPtr (hBrush);
|
||||
brushPtr->logbrush.lbStyle = lb->lbStyle;
|
||||
brushPtr->logbrush.lbColor = lb->lbColor;
|
||||
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
||||
|
||||
BRUSHOBJ_UnlockBrush (hBrush);
|
||||
DPRINT("%08x\n", hBrush);
|
||||
|
||||
|
@ -50,29 +51,26 @@ HBRUSH STDCALL W32kCreateDIBPatternBrush(HGLOBAL hDIBPacked,
|
|||
|
||||
/* Make a copy of the bitmap */
|
||||
if (!(info = (BITMAPINFO *)GlobalLock( hbitmap )))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (info->bmiHeader.biCompression)
|
||||
size = info->bmiHeader.biSizeImage;
|
||||
else
|
||||
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
|
||||
info->bmiHeader.biHeight,
|
||||
info->bmiHeader.biBitCount);
|
||||
size += DIB_BitmapInfoSize( info, coloruse );
|
||||
if (info->bmiHeader.biCompression) size = info->bmiHeader.biSizeImage;
|
||||
else
|
||||
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
|
||||
size += DIB_BitmapInfoSize(info, coloruse);
|
||||
|
||||
if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
|
||||
{
|
||||
GlobalUnlock16( hbitmap );
|
||||
return 0;
|
||||
}
|
||||
newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch );
|
||||
memcpy( newInfo, info, size );
|
||||
GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch );
|
||||
GlobalUnlock( hbitmap );
|
||||
return W32kCreateBrushIndirect( &logbrush );
|
||||
if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
|
||||
{
|
||||
GlobalUnlock16( hbitmap );
|
||||
return 0;
|
||||
}
|
||||
newInfo = (BITMAPINFO *) GlobalLock16((HGLOBAL16)logbrush.lbHatch);
|
||||
memcpy(newInfo, info, size);
|
||||
GlobalUnlock16((HGLOBAL16)logbrush.lbHatch);
|
||||
GlobalUnlock(hbitmap);
|
||||
return W32kCreateBrushIndirect(&logbrush);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -86,9 +84,9 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
|
|||
|
||||
info = (BITMAPINFO *) PackedDIB;
|
||||
if (info == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
DPRINT ("%p %ldx%ld %dbpp\n",
|
||||
info,
|
||||
info->bmiHeader.biWidth,
|
||||
|
@ -102,28 +100,23 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
|
|||
/* Make a copy of the bitmap */
|
||||
|
||||
if (info->bmiHeader.biCompression)
|
||||
{
|
||||
size = info->bmiHeader.biSizeImage;
|
||||
}
|
||||
{
|
||||
size = info->bmiHeader.biSizeImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth,
|
||||
info->bmiHeader.biHeight,
|
||||
info->bmiHeader.biBitCount);
|
||||
}
|
||||
size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
|
||||
}
|
||||
size += DIB_BitmapInfoSize (info, Usage);
|
||||
|
||||
logbrush.lbHatch = (INT)
|
||||
GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE),
|
||||
GO_MAGIC_DONTCARE);
|
||||
logbrush.lbHatch = (INT)GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE), GO_MAGIC_DONTCARE);
|
||||
if (logbrush.lbHatch == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch,
|
||||
GO_MAGIC_DONTCARE);
|
||||
memcpy (newInfo, info, size);
|
||||
GDIOBJ_UnlockObject ((HGDIOBJ) logbrush.lbHatch);
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch, GO_MAGIC_DONTCARE);
|
||||
memcpy(newInfo, info, size);
|
||||
GDIOBJ_UnlockObject((HGDIOBJ)logbrush.lbHatch);
|
||||
|
||||
return W32kCreateBrushIndirect (&logbrush);
|
||||
}
|
||||
|
@ -136,9 +129,9 @@ HBRUSH STDCALL W32kCreateHatchBrush(INT Style,
|
|||
DPRINT("%d %06lx\n", Style, Color);
|
||||
|
||||
if (Style < 0 || Style >= NB_HATCH_STYLES)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
logbrush.lbStyle = BS_HATCHED;
|
||||
logbrush.lbColor = Color;
|
||||
logbrush.lbHatch = Style;
|
||||
|
@ -153,24 +146,24 @@ HBRUSH STDCALL W32kCreatePatternBrush(HBITMAP hBitmap)
|
|||
DPRINT ("%04x\n", hBitmap);
|
||||
logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap);
|
||||
if(!logbrush.lbHatch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return W32kCreateBrushIndirect( &logbrush );
|
||||
}
|
||||
{
|
||||
return W32kCreateBrushIndirect( &logbrush );
|
||||
}
|
||||
}
|
||||
|
||||
HBRUSH STDCALL W32kCreateSolidBrush(COLORREF Color)
|
||||
{
|
||||
LOGBRUSH logbrush;
|
||||
LOGBRUSH logbrush;
|
||||
|
||||
logbrush.lbStyle = BS_SOLID;
|
||||
logbrush.lbColor = Color;
|
||||
logbrush.lbHatch = 0;
|
||||
logbrush.lbStyle = BS_SOLID;
|
||||
logbrush.lbColor = Color;
|
||||
logbrush.lbHatch = 0;
|
||||
|
||||
return W32kCreateBrushIndirect(&logbrush);
|
||||
return W32kCreateBrushIndirect(&logbrush);
|
||||
}
|
||||
|
||||
BOOL STDCALL W32kFixBrushOrgEx(VOID)
|
||||
|
|
|
@ -1,28 +1,135 @@
|
|||
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include <win32k/dc.h>
|
||||
#include <win32k/color.h>
|
||||
#include "../eng/objects.h"
|
||||
|
||||
// #define NDEBUG
|
||||
#include <win32k/debug1.h>
|
||||
|
||||
int COLOR_gapStart = 256;
|
||||
int COLOR_gapEnd = -1;
|
||||
int COLOR_gapFilled = 0;
|
||||
int COLOR_max = 256;
|
||||
|
||||
static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
|
||||
static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
|
||||
|
||||
const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
|
||||
{
|
||||
// first 10 entries in the system palette
|
||||
// red green blue flags
|
||||
{ 0x00, 0x00, 0x00, PC_SYS_USED },
|
||||
{ 0x80, 0x00, 0x00, PC_SYS_USED },
|
||||
{ 0x00, 0x80, 0x00, PC_SYS_USED },
|
||||
{ 0x80, 0x80, 0x00, PC_SYS_USED },
|
||||
{ 0x00, 0x00, 0x80, PC_SYS_USED },
|
||||
{ 0x80, 0x00, 0x80, PC_SYS_USED },
|
||||
{ 0x00, 0x80, 0x80, PC_SYS_USED },
|
||||
{ 0xc0, 0xc0, 0xc0, PC_SYS_USED },
|
||||
{ 0xc0, 0xdc, 0xc0, PC_SYS_USED },
|
||||
{ 0xa6, 0xca, 0xf0, PC_SYS_USED },
|
||||
|
||||
// ... c_min/2 dynamic colorcells
|
||||
// ... gap (for sparse palettes)
|
||||
// ... c_min/2 dynamic colorcells
|
||||
|
||||
{ 0xff, 0xfb, 0xf0, PC_SYS_USED },
|
||||
{ 0xa0, 0xa0, 0xa4, PC_SYS_USED },
|
||||
{ 0x80, 0x80, 0x80, PC_SYS_USED },
|
||||
{ 0xff, 0x00, 0x00, PC_SYS_USED },
|
||||
{ 0x00, 0xff, 0x00, PC_SYS_USED },
|
||||
{ 0xff, 0xff, 0x00, PC_SYS_USED },
|
||||
{ 0x00, 0x00, 0xff, PC_SYS_USED },
|
||||
{ 0xff, 0x00, 0xff, PC_SYS_USED },
|
||||
{ 0x00, 0xff, 0xff, PC_SYS_USED },
|
||||
{ 0xff, 0xff, 0xff, PC_SYS_USED } // last 10
|
||||
};
|
||||
|
||||
const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
|
||||
{
|
||||
return COLOR_sysPalTemplate;
|
||||
}
|
||||
|
||||
BOOL STDCALL W32kAnimatePalette(HPALETTE hpal,
|
||||
UINT StartIndex,
|
||||
UINT Entries,
|
||||
CONST PPALETTEENTRY ppe)
|
||||
{
|
||||
/*
|
||||
if( hPal != W32kGetStockObject(DEFAULT_PALETTE) )
|
||||
{
|
||||
PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
|
||||
if (!palPtr) return FALSE;
|
||||
|
||||
if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
|
||||
{
|
||||
UINT u;
|
||||
for( u = 0; u < NumEntries; u++ )
|
||||
palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
|
||||
PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette );
|
||||
GDI_ReleaseObj(hPal);
|
||||
return TRUE;
|
||||
}
|
||||
GDI_ReleaseObj(hPal);
|
||||
}
|
||||
return FALSE;
|
||||
*/
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
HPALETTE STDCALL W32kCreateHalftonePalette(HDC hDC)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
int i, r, g, b;
|
||||
struct {
|
||||
WORD Version;
|
||||
WORD NumberOfEntries;
|
||||
PALETTEENTRY aEntries[256];
|
||||
} Palette;
|
||||
|
||||
Palette.Version = 0x300;
|
||||
Palette.NumberOfEntries = 256;
|
||||
W32kGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries);
|
||||
|
||||
for (r = 0; r < 6; r++) {
|
||||
for (g = 0; g < 6; g++) {
|
||||
for (b = 0; b < 6; b++) {
|
||||
i = r + g*6 + b*36 + 10;
|
||||
Palette.aEntries[i].peRed = r * 51;
|
||||
Palette.aEntries[i].peGreen = g * 51;
|
||||
Palette.aEntries[i].peBlue = b * 51;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 216; i < 246; i++) {
|
||||
int v = (i - 216) * 8;
|
||||
Palette.aEntries[i].peRed = v;
|
||||
Palette.aEntries[i].peGreen = v;
|
||||
Palette.aEntries[i].peBlue = v;
|
||||
}
|
||||
|
||||
return W32kCreatePalette((LOGPALETTE *)&Palette);
|
||||
}
|
||||
|
||||
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE lgpl)
|
||||
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE palette)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PPALOBJ PalObj;
|
||||
HPALETTE NewPalette = EngCreatePalette(PAL_INDEXED, palette->palNumEntries, palette->palPalEntry, 0, 0, 0);
|
||||
ULONG size;
|
||||
|
||||
PalObj = AccessUserObject(NewPalette);
|
||||
|
||||
size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
|
||||
memcpy(&PalObj->logpalette, palette, size);
|
||||
PALETTE_ValidateFlags(PalObj->logpalette.palPalEntry, PalObj->logpalette.palNumEntries);
|
||||
PalObj->logicalToSystem = NULL;
|
||||
|
||||
return NewPalette;
|
||||
}
|
||||
|
||||
BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
|
||||
|
@ -34,13 +141,43 @@ BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
|
|||
COLORREF STDCALL W32kGetNearestColor(HDC hDC,
|
||||
COLORREF Color)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
COLORREF nearest = CLR_INVALID;
|
||||
PDC dc;
|
||||
PPALOBJ palObj;
|
||||
|
||||
if(DC_HandleToPtr(hDC))
|
||||
{
|
||||
HPALETTE hpal = (dc->w.hPalette)? dc->w.hPalette : W32kGetStockObject(DEFAULT_PALETTE);
|
||||
palObj = AccessUserObject(hpal);
|
||||
if (!palObj) {
|
||||
// GDI_ReleaseObj(hdc);
|
||||
return nearest;
|
||||
}
|
||||
|
||||
nearest = COLOR_LookupNearestColor(palObj->logpalette.palPalEntry,
|
||||
palObj->logpalette.palNumEntries, Color);
|
||||
|
||||
// GDI_ReleaseObj( hpal );
|
||||
// GDI_ReleaseObj( hdc );
|
||||
}
|
||||
|
||||
return nearest;
|
||||
}
|
||||
|
||||
UINT STDCALL W32kGetNearestPaletteIndex(HPALETTE hpal,
|
||||
COLORREF Color)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PPALOBJ palObj = AccessUserObject(hpal);
|
||||
UINT index = 0;
|
||||
|
||||
if( palObj )
|
||||
{
|
||||
// Return closest match for the given RGB color
|
||||
index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry, palObj->logpalette.palNumEntries, NULL, Color, FALSE);
|
||||
// GDI_ReleaseObj( hpalette );
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
|
||||
|
@ -48,7 +185,29 @@ UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
|
|||
UINT Entries,
|
||||
LPPALETTEENTRY pe)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PPALOBJ palPtr;
|
||||
UINT numEntries;
|
||||
|
||||
palPtr = AccessUserObject(hpal);
|
||||
if (!palPtr) return 0;
|
||||
|
||||
numEntries = palPtr->logpalette.palNumEntries;
|
||||
if (StartIndex + Entries > numEntries) Entries = numEntries - StartIndex;
|
||||
if (pe)
|
||||
{
|
||||
if (StartIndex >= numEntries)
|
||||
{
|
||||
// GDI_ReleaseObj( hpalette );
|
||||
return 0;
|
||||
}
|
||||
memcpy(pe, &palPtr->logpalette.palPalEntry[StartIndex], Entries * sizeof(PALETTEENTRY));
|
||||
for(numEntries = 0; numEntries < Entries ; numEntries++)
|
||||
if (pe[numEntries].peFlags & 0xF0)
|
||||
pe[numEntries].peFlags = 0;
|
||||
}
|
||||
|
||||
// GDI_ReleaseObj( hpalette );
|
||||
return Entries;
|
||||
}
|
||||
|
||||
UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
|
||||
|
@ -56,7 +215,33 @@ UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
|
|||
UINT Entries,
|
||||
LPPALETTEENTRY pe)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
UINT i;
|
||||
PDC dc;
|
||||
/*
|
||||
if (!(dc = AccessUserObject(hdc))) return 0;
|
||||
|
||||
if (!pe)
|
||||
{
|
||||
Entries = dc->devCaps->sizePalette;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (StartIndex >= dc->devCaps->sizePalette)
|
||||
{
|
||||
Entries = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (StartIndex + Entries >= dc->devCaps->sizePalette) Entries = dc->devCaps->sizePalette - StartIndex;
|
||||
|
||||
for (i = 0; i < Entries; i++)
|
||||
{
|
||||
*(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
|
||||
}
|
||||
|
||||
done:
|
||||
// GDI_ReleaseObj(hdc);
|
||||
return count; */
|
||||
}
|
||||
|
||||
UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
|
||||
|
@ -65,13 +250,112 @@ UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
|
|||
}
|
||||
|
||||
UINT STDCALL W32kRealizePalette(HDC hDC)
|
||||
/*
|
||||
The RealizePalette function modifies the palette for the device associated with the specified device context. If the device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device context is a display DC, the physical palette for that device is modified.
|
||||
|
||||
A logical palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows.
|
||||
|
||||
1= IF DRAWING TO A DEVICE
|
||||
-- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
|
||||
the system palette.
|
||||
-- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
|
||||
|
||||
2= IF DRAWING TO A MEMORY DC\BITMAP
|
||||
-- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
|
||||
the dc palette.
|
||||
-- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PPALOBJ palPtr, sysPtr;
|
||||
PPALGDI palGDI, sysGDI;
|
||||
int realized = 0;
|
||||
PDC dc = AccessUserObject(hDC);
|
||||
HPALETTE systemPalette;
|
||||
PSURFGDI SurfGDI;
|
||||
BOOLEAN success;
|
||||
|
||||
if (!dc) return 0;
|
||||
|
||||
palPtr = AccessUserObject(dc->w.hPalette);
|
||||
SurfGDI = AccessInternalObjectFromUserObject(dc->Surface);
|
||||
systemPalette = W32kGetStockObject(STOCK_DEFAULT_PALETTE);
|
||||
sysPtr = AccessInternalObject(systemPalette);
|
||||
palGDI = AccessInternalObject(dc->w.hPalette);
|
||||
sysGDI = AccessInternalObject(systemPalette);
|
||||
|
||||
// Step 1: Create mapping of system palette\DC palette
|
||||
realized = PALETTE_SetMapping(palPtr, 0, palPtr->logpalette.palNumEntries,
|
||||
(dc->w.hPalette != hPrimaryPalette) ||
|
||||
(dc->w.hPalette == W32kGetStockObject(DEFAULT_PALETTE)));
|
||||
|
||||
// Step 2:
|
||||
// The RealizePalette function modifies the palette for the device associated with the specified device context. If the
|
||||
// device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
|
||||
// context is a display DC, the physical palette for that device is modified.
|
||||
if(dc->w.flags == DC_MEMORY)
|
||||
{
|
||||
// Memory managed DC
|
||||
DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
|
||||
} else {
|
||||
if(SurfGDI->SetPalette)
|
||||
{
|
||||
success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysPtr->logpalette.palNumEntries);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Create the XLATEOBJ for device managed DCs
|
||||
if(dc->w.flags != DC_MEMORY)
|
||||
{
|
||||
// Device managed DC
|
||||
palPtr->logicalToSystem = EngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette);
|
||||
}
|
||||
|
||||
// GDI_ReleaseObj(dc->w.hPalette);
|
||||
// GDI_ReleaseObj(hdc);
|
||||
|
||||
return realized;
|
||||
}
|
||||
|
||||
BOOL STDCALL W32kResizePalette(HPALETTE hpal,
|
||||
UINT Entries)
|
||||
{
|
||||
/* PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
|
||||
UINT cPrevEnt, prevVer;
|
||||
INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
|
||||
PXLATEOBJ XlateObj = NULL;
|
||||
|
||||
if(!palPtr) return FALSE;
|
||||
cPrevEnt = palPtr->logpalette.palNumEntries;
|
||||
prevVer = palPtr->logpalette.palVersion;
|
||||
prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
|
||||
size += sizeof(int*) + sizeof(GDIOBJHDR);
|
||||
XlateObj = palPtr->logicalToSystem;
|
||||
|
||||
if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
|
||||
|
||||
if(XlateObj)
|
||||
{
|
||||
PXLATEOBJ NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
|
||||
if(NewXlateObj == NULL)
|
||||
{
|
||||
ERR("Can not resize logicalToSystem -- out of memory!");
|
||||
GDI_ReleaseObj( hPal );
|
||||
return FALSE;
|
||||
}
|
||||
palPtr->logicalToSystem = NewXlateObj;
|
||||
}
|
||||
|
||||
if(cEntries > cPrevEnt)
|
||||
{
|
||||
if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
|
||||
memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
|
||||
PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
|
||||
}
|
||||
palPtr->logpalette.palNumEntries = cEntries;
|
||||
palPtr->logpalette.palVersion = prevVer;
|
||||
// GDI_ReleaseObj( hPal );
|
||||
return TRUE; */
|
||||
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -79,7 +363,15 @@ HPALETTE STDCALL W32kSelectPalette(HDC hDC,
|
|||
HPALETTE hpal,
|
||||
BOOL ForceBackground)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PDC dc = AccessUserObject(hDC);
|
||||
HPALETTE oldPal;
|
||||
|
||||
oldPal = dc->w.hPalette;
|
||||
dc->w.hPalette = hpal;
|
||||
|
||||
// FIXME: mark the palette as a [fore\back]ground pal
|
||||
|
||||
return oldPal;
|
||||
}
|
||||
|
||||
BOOL STDCALL W32kSetColorAdjustment(HDC hDC,
|
||||
|
@ -93,7 +385,25 @@ UINT STDCALL W32kSetPaletteEntries(HPALETTE hpal,
|
|||
UINT Entries,
|
||||
CONST LPPALETTEENTRY pe)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PPALOBJ palPtr;
|
||||
INT numEntries;
|
||||
|
||||
palPtr = AccessUserObject(hpal);
|
||||
if (!palPtr) return 0;
|
||||
|
||||
numEntries = palPtr->logpalette.palNumEntries;
|
||||
if (Start >= numEntries)
|
||||
{
|
||||
// GDI_ReleaseObj( hpalette );
|
||||
return 0;
|
||||
}
|
||||
if (Start + Entries > numEntries) Entries = numEntries - Start;
|
||||
memcpy(&palPtr->logpalette.palPalEntry[Start], pe, Entries * sizeof(PALETTEENTRY));
|
||||
PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, palPtr->logpalette.palNumEntries);
|
||||
ExFreePool(palPtr->logicalToSystem);
|
||||
palPtr->logicalToSystem = NULL;
|
||||
// GDI_ReleaseObj( hpalette );
|
||||
return Entries;
|
||||
}
|
||||
|
||||
UINT STDCALL W32kSetSystemPaletteUse(HDC hDC,
|
||||
|
@ -109,6 +419,81 @@ BOOL STDCALL W32kUnrealizeObject(HGDIOBJ hgdiobj)
|
|||
|
||||
BOOL STDCALL W32kUpdateColors(HDC hDC)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PDC dc;
|
||||
HWND hWnd;
|
||||
int size;
|
||||
/*
|
||||
if (!(dc = AccessUserObject(hDC))) return 0;
|
||||
size = dc->devCaps->sizePalette;
|
||||
// GDI_ReleaseObj( hDC );
|
||||
|
||||
if (Callout.WindowFromDC)
|
||||
{
|
||||
hWnd = Callout.WindowFromDC( hDC );
|
||||
|
||||
// Docs say that we have to remap current drawable pixel by pixel
|
||||
// but it would take forever given the speed of XGet/PutPixel.
|
||||
if (hWnd && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
|
||||
} */
|
||||
return 0x666;
|
||||
}
|
||||
|
||||
int COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, int size,
|
||||
PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved)
|
||||
{
|
||||
int i, best = 0, diff = 0x7fffffff;
|
||||
int r, g, b;
|
||||
|
||||
for( i = 0; i < size && diff ; i++ )
|
||||
{
|
||||
if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
|
||||
continue;
|
||||
|
||||
r = palPalEntry[i].peRed - GetRValue(col);
|
||||
g = palPalEntry[i].peGreen - GetGValue(col);
|
||||
b = palPalEntry[i].peBlue - GetBValue(col);
|
||||
|
||||
r = r*r + g*g + b*b;
|
||||
|
||||
if( r < diff ) { best = i; diff = r; }
|
||||
}
|
||||
return (XlateObj->pulXlate) ? XlateObj->pulXlate[best] : best;
|
||||
}
|
||||
|
||||
COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
|
||||
{
|
||||
unsigned char spec_type = color >> 24;
|
||||
int i;
|
||||
PALETTEENTRY *COLOR_sysPal = ReturnSystemPalette();
|
||||
|
||||
// we need logical palette for PALETTERGB and PALETTEINDEX colorrefs
|
||||
|
||||
if( spec_type == 2 ) /* PALETTERGB */
|
||||
color = *(COLORREF*)(palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
|
||||
|
||||
else if( spec_type == 1 ) /* PALETTEINDEX */
|
||||
{
|
||||
if( (i = color & 0x0000ffff) >= size )
|
||||
{
|
||||
DbgPrint("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
|
||||
color = *(COLORREF*)palPalEntry;
|
||||
}
|
||||
else color = *(COLORREF*)(palPalEntry + i);
|
||||
}
|
||||
|
||||
color &= 0x00ffffff;
|
||||
return (0x00ffffff & *(COLORREF*)(COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
|
||||
}
|
||||
|
||||
int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
|
||||
COLORREF col )
|
||||
{
|
||||
int i;
|
||||
BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
|
||||
for( i = 0; i < size; i++ )
|
||||
{
|
||||
if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
|
||||
if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -17,23 +17,17 @@ BOOL STDCALL W32kCombineTransform(LPXFORM XFormResult,
|
|||
|
||||
/* Check for illegal parameters */
|
||||
if (!XFormResult || !xform1 || !xform2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Create the result in a temporary XFORM, since xformResult may be
|
||||
* equal to xform1 or xform2 */
|
||||
xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
|
||||
xform1->eM12 * xform2->eM21;
|
||||
xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
|
||||
xform1->eM12 * xform2->eM22;
|
||||
xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
|
||||
xform1->eM22 * xform2->eM21;
|
||||
xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
|
||||
xform1->eM22 * xform2->eM22;
|
||||
xformTemp.eDx = xform1->eDx * xform2->eM11 +
|
||||
xform1->eDy * xform2->eM21 + xform2->eDx;
|
||||
xformTemp.eDy = xform1->eDx * xform2->eM12 +
|
||||
xform1->eDy * xform2->eM22 + xform2->eDy;
|
||||
xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
|
||||
xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
|
||||
xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
|
||||
xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
|
||||
xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
|
||||
xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
|
||||
|
||||
/* Copy the result to xformResult */
|
||||
*XFormResult = xformTemp;
|
||||
|
@ -57,9 +51,9 @@ W32kGetGraphicsMode(HDC hDC)
|
|||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GraphicsMode = dc->w.GraphicsMode;
|
||||
DC_UnlockDC (hDC);
|
||||
|
@ -76,13 +70,13 @@ W32kGetWorldTransform(HDC hDC,
|
|||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!XForm)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*XForm = dc->w.xformWorld2Wnd;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
|
@ -108,22 +102,22 @@ W32kModifyWorldTransform(HDC hDC,
|
|||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
// SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
// SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
if (!XForm)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check that graphics mode is GM_ADVANCED */
|
||||
if (dc->w.GraphicsMode!=GM_ADVANCED)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
switch (Mode)
|
||||
{
|
||||
{
|
||||
case MWT_IDENTITY:
|
||||
dc->w.xformWorld2Wnd.eM11 = 1.0f;
|
||||
dc->w.xformWorld2Wnd.eM12 = 0.0f;
|
||||
|
@ -134,20 +128,16 @@ W32kModifyWorldTransform(HDC hDC,
|
|||
break;
|
||||
|
||||
case MWT_LEFTMULTIPLY:
|
||||
W32kCombineTransform(&dc->w.xformWorld2Wnd,
|
||||
XForm,
|
||||
&dc->w.xformWorld2Wnd );
|
||||
W32kCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd );
|
||||
break;
|
||||
|
||||
case MWT_RIGHTMULTIPLY:
|
||||
W32kCombineTransform(&dc->w.xformWorld2Wnd,
|
||||
&dc->w.xformWorld2Wnd,
|
||||
XForm);
|
||||
W32kCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
DC_UpdateXforms (dc);
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
|
@ -208,9 +198,9 @@ W32kSetGraphicsMode(HDC hDC,
|
|||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* One would think that setting the graphics mode to GM_COMPATIBLE
|
||||
* would also reset the world transformation matrix to the unity
|
||||
|
@ -219,9 +209,9 @@ W32kSetGraphicsMode(HDC hDC,
|
|||
*/
|
||||
|
||||
if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ret = dc->w.GraphicsMode;
|
||||
dc->w.GraphicsMode = Mode;
|
||||
DC_UnlockDC (hDC);
|
||||
|
@ -286,20 +276,20 @@ W32kSetWorldTransform(HDC hDC,
|
|||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
// SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
// SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
if (!XForm)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check that graphics mode is GM_ADVANCED */
|
||||
if (dc->w.GraphicsMode != GM_ADVANCED)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
dc->w.xformWorld2Wnd = *XForm;
|
||||
DC_UpdateXforms (dc);
|
||||
DC_UnlockDC (hDC);
|
||||
|
|
File diff suppressed because it is too large
Load diff
703
reactos/subsys/win32k/objects/dib.c
Normal file
703
reactos/subsys/win32k/objects/dib.c
Normal file
|
@ -0,0 +1,703 @@
|
|||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <win32k/bitmaps.h>
|
||||
#include <win32k/debug.h>
|
||||
#include <debug.h>
|
||||
#include "../eng/objects.h"
|
||||
#include <ntos/minmax.h>
|
||||
|
||||
UINT STDCALL W32kSetDIBColorTable(HDC hDC,
|
||||
UINT StartIndex,
|
||||
UINT Entries,
|
||||
CONST RGBQUAD *Colors)
|
||||
{
|
||||
PDC dc;
|
||||
PALETTEENTRY * palEntry;
|
||||
PPALOBJ palette;
|
||||
RGBQUAD *end;
|
||||
|
||||
if (!(dc = AccessUserObject(hDC))) return 0;
|
||||
|
||||
if (!(palette = AccessUserObject(dc->DevInfo.hpalDefault)))
|
||||
{
|
||||
// GDI_ReleaseObj( hdc );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Transfer color info
|
||||
|
||||
if (dc->w.bitsPerPixel <= 8) {
|
||||
palEntry = palette->logpalette.palPalEntry + StartIndex;
|
||||
if (StartIndex + Entries > (1 << dc->w.bitsPerPixel))
|
||||
Entries = (1 << dc->w.bitsPerPixel) - StartIndex;
|
||||
|
||||
if (StartIndex + Entries > palette->logpalette.palNumEntries)
|
||||
Entries = palette->logpalette.palNumEntries - StartIndex;
|
||||
|
||||
for (end = Colors + Entries; Colors < end; palEntry++, Colors++)
|
||||
{
|
||||
palEntry->peRed = Colors->rgbRed;
|
||||
palEntry->peGreen = Colors->rgbGreen;
|
||||
palEntry->peBlue = Colors->rgbBlue;
|
||||
}
|
||||
} else {
|
||||
Entries = 0;
|
||||
}
|
||||
|
||||
// GDI_ReleaseObj(dc->DevInfo.hpalDefault);
|
||||
// GDI_ReleaseObj(hdc);
|
||||
|
||||
return Entries;
|
||||
}
|
||||
|
||||
// Converts a DIB to a device-dependent bitmap
|
||||
INT STDCALL W32kSetDIBits(HDC hDC,
|
||||
HBITMAP hBitmap,
|
||||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT ColorUse)
|
||||
{
|
||||
DC *dc;
|
||||
BITMAPOBJ *bitmap;
|
||||
HBITMAP SourceBitmap, DestBitmap;
|
||||
INT result;
|
||||
BOOL copyBitsResult;
|
||||
PSURFOBJ DestSurf, SourceSurf;
|
||||
PSURFGDI DestGDI;
|
||||
SIZEL SourceSize;
|
||||
POINTL ZeroPoint;
|
||||
RECTL DestRect;
|
||||
PXLATEOBJ XlateObj;
|
||||
PPALGDI hDCPalette;
|
||||
RGBQUAD *lpRGB;
|
||||
HPALETTE DDB_Palette, DIB_Palette;
|
||||
USHORT DDB_Palette_Type, DIB_Palette_Type;
|
||||
|
||||
|
||||
// Check parameters
|
||||
if (!(dc = DC_HandleToPtr(hDC))) return 0;
|
||||
|
||||
if (!(bitmap = (BITMAPOBJ *)GDIOBJ_HandleToPtr(hBitmap, GO_BITMAP_MAGIC)))
|
||||
{
|
||||
// GDI_ReleaseObj(hDC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get RGB values
|
||||
if (ColorUse == DIB_PAL_COLORS)
|
||||
lpRGB = DIB_MapPaletteColors(hDC, bmi);
|
||||
else
|
||||
lpRGB = &bmi->bmiColors[0];
|
||||
|
||||
// Create a temporary surface for the destination bitmap
|
||||
DestSurf = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
|
||||
DestGDI = ExAllocatePool(PagedPool, sizeof(SURFGDI));
|
||||
DestBitmap = CreateGDIHandle(DestGDI, DestSurf);
|
||||
|
||||
BitmapToSurf(hDC, DestGDI, DestSurf, bitmap);
|
||||
|
||||
// Create source surface
|
||||
SourceSize.cx = bmi->bmiHeader.biWidth;
|
||||
SourceSize.cy = bmi->bmiHeader.biHeight;
|
||||
SourceBitmap = EngCreateBitmap(SourceSize, DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount),
|
||||
BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
|
||||
0, Bits);
|
||||
SourceSurf = AccessUserObject(SourceBitmap);
|
||||
|
||||
// Destination palette obtained from the hDC
|
||||
hDCPalette = AccessInternalObject(dc->DevInfo.hpalDefault);
|
||||
DDB_Palette_Type = hDCPalette->Mode;
|
||||
DDB_Palette = dc->DevInfo.hpalDefault;
|
||||
|
||||
// Source palette obtained from the BITMAPINFO
|
||||
DIB_Palette = BuildDIBPalette(bmi, &DIB_Palette_Type);
|
||||
|
||||
// Determine XLATEOBJ for color translation
|
||||
XlateObj = EngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
|
||||
|
||||
// Determine destination rectangle and source point
|
||||
ZeroPoint.x = 0;
|
||||
ZeroPoint.y = 0;
|
||||
DestRect.top = 0;
|
||||
DestRect.left = 0;
|
||||
DestRect.right = SourceSize.cx;
|
||||
DestRect.bottom = SourceSize.cy;
|
||||
|
||||
copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
|
||||
|
||||
// Clean up
|
||||
EngDeleteSurface(SourceBitmap);
|
||||
EngDeleteSurface(DestBitmap);
|
||||
|
||||
// if (ColorUse == DIB_PAL_COLORS)
|
||||
// WinFree((LPSTR)lpRGB);
|
||||
|
||||
// GDI_ReleaseObj(hBitmap); unlock?
|
||||
// GDI_ReleaseObj(hDC);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
INT STDCALL W32kSetDIBitsToDevice(HDC hDC,
|
||||
INT XDest,
|
||||
INT YDest,
|
||||
DWORD Width,
|
||||
DWORD Height,
|
||||
INT XSrc,
|
||||
INT YSrc,
|
||||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT ColorUse)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UINT STDCALL W32kGetDIBColorTable(HDC hDC,
|
||||
UINT StartIndex,
|
||||
UINT Entries,
|
||||
RGBQUAD *Colors)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
// Converts a device-dependent bitmap to a DIB
|
||||
INT STDCALL W32kGetDIBits(HDC hDC,
|
||||
HBITMAP hBitmap,
|
||||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
LPVOID Bits,
|
||||
LPBITMAPINFO bi,
|
||||
UINT Usage)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
INT STDCALL W32kStretchDIBits(HDC hDC,
|
||||
INT XDest,
|
||||
INT YDest,
|
||||
INT DestWidth,
|
||||
INT DestHeight,
|
||||
INT XSrc,
|
||||
INT YSrc,
|
||||
INT SrcWidth,
|
||||
INT SrcHeight,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPINFO *BitsInfo,
|
||||
UINT Usage,
|
||||
DWORD ROP)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
|
||||
LONG Count,
|
||||
LPVOID Bits)
|
||||
{
|
||||
PBITMAPOBJ bmp;
|
||||
LONG height, ret;
|
||||
|
||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||
if (!bmp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the bits vector is null, the function should return the read size */
|
||||
if (Bits == NULL)
|
||||
{
|
||||
return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
|
||||
}
|
||||
|
||||
if (Count < 0)
|
||||
{
|
||||
DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
|
||||
Count = -Count;
|
||||
}
|
||||
|
||||
/* Only get entire lines */
|
||||
height = Count / bmp->bitmap.bmWidthBytes;
|
||||
if (height > bmp->bitmap.bmHeight)
|
||||
{
|
||||
height = bmp->bitmap.bmHeight;
|
||||
}
|
||||
Count = height * bmp->bitmap.bmWidthBytes;
|
||||
if (Count == 0)
|
||||
{
|
||||
DPRINT("Less then one entire line requested\n");
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
|
||||
hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
|
||||
1 << bmp->bitmap.bmBitsPixel, height );
|
||||
#if 0
|
||||
/* FIXME: Call DDI CopyBits here if available */
|
||||
if(bmp->DDBitmap)
|
||||
{
|
||||
DPRINT("Calling device specific BitmapBits\n");
|
||||
if(bmp->DDBitmap->funcs->pBitmapBits)
|
||||
{
|
||||
ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
|
||||
DDB_GET);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR_(bitmap)("BitmapBits == NULL??\n");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(!bmp->bitmap.bmBits)
|
||||
{
|
||||
DPRINT ("Bitmap is empty\n");
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(Bits, bmp->bitmap.bmBits, Count);
|
||||
ret = Count;
|
||||
}
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
|
||||
// The DDB that is created will be whatever bit depth your reference DC is
|
||||
HBITMAP STDCALL W32kCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header,
|
||||
DWORD init, LPCVOID bits, const BITMAPINFO *data,
|
||||
UINT coloruse)
|
||||
{
|
||||
HBITMAP handle;
|
||||
BOOL fColor;
|
||||
DWORD width;
|
||||
int height;
|
||||
WORD bpp;
|
||||
WORD compr;
|
||||
|
||||
if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
|
||||
if (height < 0) height = -height;
|
||||
|
||||
// Check if we should create a monochrome or color bitmap.
|
||||
// We create a monochrome bitmap only if it has exactly 2
|
||||
// colors, which are black followed by white, nothing else.
|
||||
// In all other cases, we create a color bitmap.
|
||||
|
||||
if (bpp != 1) fColor = TRUE;
|
||||
else if ((coloruse != DIB_RGB_COLORS) ||
|
||||
(init != CBM_INIT) || !data) fColor = FALSE;
|
||||
else
|
||||
{
|
||||
if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||
{
|
||||
RGBQUAD *rgb = data->bmiColors;
|
||||
DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
|
||||
|
||||
// Check if the first color of the colormap is black
|
||||
if ((col == RGB(0, 0, 0)))
|
||||
{
|
||||
rgb++;
|
||||
col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
|
||||
// If the second color is white, create a monochrome bitmap
|
||||
fColor = (col != RGB(0xff,0xff,0xff));
|
||||
}
|
||||
// Note : If the first color of the colormap is white
|
||||
// followed by black, we have to create a color bitmap.
|
||||
// If we don't the white will be displayed in black later on!
|
||||
else fColor = TRUE;
|
||||
}
|
||||
else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
|
||||
DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
|
||||
|
||||
if ((col == RGB(0,0,0)))
|
||||
{
|
||||
rgb++;
|
||||
col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
|
||||
fColor = (col != RGB(0xff,0xff,0xff));
|
||||
}
|
||||
else fColor = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("(%ld): wrong size for data\n", data->bmiHeader.biSize );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Now create the bitmap
|
||||
|
||||
if (fColor)
|
||||
{
|
||||
handle = W32kCreateCompatibleBitmap(RetrieveDisplayHDC(), width, height);
|
||||
}
|
||||
else handle = W32kCreateBitmap(width, height, 1, 1, NULL);
|
||||
|
||||
if (!handle) return 0;
|
||||
|
||||
if (init == CBM_INIT)
|
||||
{
|
||||
W32kSetDIBits(hdc, handle, 0, height, bits, data, coloruse);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT Usage,
|
||||
VOID *Bits,
|
||||
HANDLE hSection,
|
||||
DWORD dwOffset)
|
||||
{
|
||||
HBITMAP hbitmap = 0;
|
||||
DC *dc;
|
||||
BOOL bDesktopDC = FALSE;
|
||||
|
||||
// If the reference hdc is null, take the desktop dc
|
||||
if (hDC == 0)
|
||||
{
|
||||
hDC = W32kCreateCompatableDC(0);
|
||||
bDesktopDC = TRUE;
|
||||
}
|
||||
|
||||
if ((dc = DC_HandleToPtr(hDC)))
|
||||
{
|
||||
hbitmap = DIB_CreateDIBSection(dc, bmi, Usage, Bits, hSection, dwOffset, 0);
|
||||
DC_UnlockDC (hDC);
|
||||
}
|
||||
|
||||
if (bDesktopDC)
|
||||
W32kDeleteDC(hDC);
|
||||
|
||||
return hbitmap;
|
||||
}
|
||||
|
||||
HBITMAP DIB_CreateDIBSection(
|
||||
PDC dc, BITMAPINFO *bmi, UINT usage,
|
||||
LPVOID *bits, HANDLE section,
|
||||
DWORD offset, DWORD ovr_pitch)
|
||||
{
|
||||
HBITMAP res = 0;
|
||||
BITMAPOBJ *bmp = NULL;
|
||||
DIBSECTION *dib = NULL;
|
||||
int *colorMap = NULL;
|
||||
int nColorMap;
|
||||
|
||||
// Fill BITMAP32 structure with DIB data
|
||||
BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
||||
INT effHeight, totalSize;
|
||||
BITMAP bm;
|
||||
|
||||
DbgPrint("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
|
||||
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
|
||||
bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
|
||||
|
||||
effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
|
||||
bm.bmType = 0;
|
||||
bm.bmWidth = bi->biWidth;
|
||||
bm.bmHeight = effHeight;
|
||||
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
|
||||
|
||||
bm.bmPlanes = bi->biPlanes;
|
||||
bm.bmBitsPixel = bi->biBitCount;
|
||||
bm.bmBits = NULL;
|
||||
|
||||
// Get storage location for DIB bits. Only use biSizeImage if it's valid and
|
||||
// we're dealing with a compressed bitmap. Otherwise, use width * height.
|
||||
totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
|
||||
? bi->biSizeImage : bm.bmWidthBytes * effHeight;
|
||||
|
||||
/*
|
||||
if (section)
|
||||
bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
|
||||
0L, offset, totalSize);
|
||||
else if (ovr_pitch && offset)
|
||||
bm.bmBits = (LPVOID) offset;
|
||||
else { */
|
||||
offset = 0;
|
||||
/* bm.bmBits = VirtualAlloc(NULL, totalSize,
|
||||
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); */
|
||||
|
||||
bm.bmBits = ExAllocatePool(NonPagedPool, totalSize);
|
||||
|
||||
/* } */
|
||||
|
||||
if (usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *));
|
||||
|
||||
// Allocate Memory for DIB and fill structure
|
||||
if (bm.bmBits)
|
||||
dib = ExAllocatePool(PagedPool, sizeof(DIBSECTION));
|
||||
RtlZeroMemory(dib, sizeof(DIBSECTION));
|
||||
|
||||
if (dib)
|
||||
{
|
||||
dib->dsBm = bm;
|
||||
dib->dsBmih = *bi;
|
||||
dib->dsBmih.biSizeImage = totalSize;
|
||||
|
||||
/* Set dsBitfields values */
|
||||
if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
|
||||
{
|
||||
dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
|
||||
}
|
||||
else switch(bi->biBitCount)
|
||||
{
|
||||
case 16:
|
||||
dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
|
||||
dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
|
||||
dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
dib->dsBitfields[0] = 0xff;
|
||||
dib->dsBitfields[1] = 0xff00;
|
||||
dib->dsBitfields[2] = 0xff0000;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
|
||||
dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
|
||||
dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
|
||||
break;
|
||||
}
|
||||
dib->dshSection = section;
|
||||
dib->dsOffset = offset;
|
||||
}
|
||||
|
||||
// Create Device Dependent Bitmap and add DIB pointer
|
||||
if (dib)
|
||||
{
|
||||
res = W32kCreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
|
||||
if (res)
|
||||
{
|
||||
bmp = BITMAPOBJ_HandleToPtr (res);
|
||||
if (bmp)
|
||||
{
|
||||
bmp->dib = (DIBSECTION *) dib;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up in case of errors
|
||||
if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
|
||||
{
|
||||
DbgPrint("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits);
|
||||
/* if (bm.bmBits)
|
||||
{
|
||||
if (section)
|
||||
UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
|
||||
else if (!offset)
|
||||
VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
|
||||
} */
|
||||
|
||||
if (colorMap) { ExFreePool(colorMap); colorMap = NULL; }
|
||||
if (dib) { ExFreePool(dib); dib = NULL; }
|
||||
if (bmp) { BITMAPOBJ_UnlockBitmap(res); bmp = NULL; }
|
||||
if (res) { GDIOBJ_FreeObject(res, GO_BITMAP_MAGIC); res = 0; }
|
||||
}
|
||||
|
||||
// Install fault handler, if possible
|
||||
/* if (bm.bmBits)
|
||||
{
|
||||
if (VIRTUAL_SetFaultHandler(bm.bmBits, DIB_FaultHandler, (LPVOID)res))
|
||||
{
|
||||
if (section || offset)
|
||||
{
|
||||
DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
|
||||
if (dib) dib->status = DIB_AppMod;
|
||||
}
|
||||
else
|
||||
{
|
||||
DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
|
||||
if (dib) dib->status = DIB_InSync;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
// Return BITMAP handle and storage location
|
||||
if (bmp) BITMAPOBJ_UnlockBitmap(res);
|
||||
if (bm.bmBits && bits) *bits = bm.bmBits;
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetDIBWidthBytes
|
||||
*
|
||||
* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
|
||||
* http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
|
||||
* 11/16/1999 (RJJ) lifted from wine
|
||||
*/
|
||||
int DIB_GetDIBWidthBytes(int width, int depth)
|
||||
{
|
||||
int words;
|
||||
|
||||
switch(depth)
|
||||
{
|
||||
case 1: words = (width + 31) / 32; break;
|
||||
case 4: words = (width + 7) / 8; break;
|
||||
case 8: words = (width + 3) / 4; break;
|
||||
case 15:
|
||||
case 16: words = (width + 1) / 2; break;
|
||||
case 24: words = (width * 3 + 3)/4; break;
|
||||
|
||||
default:
|
||||
DPRINT("(%d): Unsupported depth\n", depth );
|
||||
/* fall through */
|
||||
case 32:
|
||||
words = width;
|
||||
}
|
||||
return 4 * words;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetDIBImageBytes
|
||||
*
|
||||
* Return the number of bytes used to hold the image in a DIB bitmap.
|
||||
* 11/16/1999 (RJJ) lifted from wine
|
||||
*/
|
||||
|
||||
int DIB_GetDIBImageBytes (int width, int height, int depth)
|
||||
{
|
||||
return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_BitmapInfoSize
|
||||
*
|
||||
* Return the size of the bitmap info structure including color table.
|
||||
* 11/16/1999 (RJJ) lifted from wine
|
||||
*/
|
||||
|
||||
int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
|
||||
{
|
||||
int colors;
|
||||
|
||||
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
|
||||
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
|
||||
return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
|
||||
}
|
||||
else /* assume BITMAPINFOHEADER */
|
||||
{
|
||||
colors = info->bmiHeader.biClrUsed;
|
||||
if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
|
||||
return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
|
||||
}
|
||||
}
|
||||
|
||||
int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
|
||||
int *height, WORD *bpp, WORD *compr )
|
||||
{
|
||||
if (header->biSize == sizeof(BITMAPINFOHEADER))
|
||||
{
|
||||
*width = header->biWidth;
|
||||
*height = header->biHeight;
|
||||
*bpp = header->biBitCount;
|
||||
*compr = header->biCompression;
|
||||
return 1;
|
||||
}
|
||||
if (header->biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
|
||||
*width = core->bcWidth;
|
||||
*height = core->bcHeight;
|
||||
*bpp = core->bcBitCount;
|
||||
*compr = 0;
|
||||
return 0;
|
||||
}
|
||||
DbgPrint("(%ld): wrong size for header\n", header->biSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Converts a Device Independent Bitmap (DIB) to a Device Dependant Bitmap (DDB)
|
||||
// The specified Device Context (DC) defines what the DIB should be converted to
|
||||
PBITMAPOBJ DIBtoDDB(HGLOBAL hPackedDIB, HDC hdc) // FIXME: This should be removed. All references to this function should
|
||||
// change to W32kSetDIBits
|
||||
{
|
||||
HBITMAP hBmp = 0;
|
||||
PBITMAPOBJ pBmp = NULL;
|
||||
DIBSECTION *dib;
|
||||
LPBYTE pbits = NULL;
|
||||
|
||||
// Get a pointer to the packed DIB's data
|
||||
// pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
|
||||
dib = hPackedDIB;
|
||||
|
||||
pbits = (dib + DIB_BitmapInfoSize(&dib->dsBmih, DIB_RGB_COLORS));
|
||||
|
||||
// Create a DDB from the DIB
|
||||
hBmp = W32kCreateDIBitmap(hdc, &dib->dsBmih, CBM_INIT, (LPVOID)pbits, &dib->dsBmih, DIB_RGB_COLORS);
|
||||
|
||||
// GlobalUnlock(hPackedDIB);
|
||||
|
||||
// Retrieve the internal Pixmap from the DDB
|
||||
pBmp = (BITMAPOBJ *)GDIOBJ_HandleToPtr(hBmp, GO_BITMAP_MAGIC);
|
||||
|
||||
return pBmp;
|
||||
}
|
||||
|
||||
RGBQUAD *DIB_MapPaletteColors(PDC dc, LPBITMAPINFO lpbmi)
|
||||
{
|
||||
RGBQUAD *lpRGB;
|
||||
int nNumColors,i;
|
||||
DWORD *lpIndex;
|
||||
PPALOBJ palObj;
|
||||
|
||||
palObj = AccessUserObject(dc->DevInfo.hpalDefault);
|
||||
|
||||
if (palObj == NULL) {
|
||||
// RELEASEDCINFO(hDC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
|
||||
if (lpbmi->bmiHeader.biClrUsed)
|
||||
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
|
||||
|
||||
lpRGB = (RGBQUAD *)ExAllocatePool(NonPagedPool, sizeof(RGBQUAD) * nNumColors);
|
||||
lpIndex = (DWORD *)&lpbmi->bmiColors[0];
|
||||
|
||||
for (i=0; i<nNumColors; i++) {
|
||||
pRGB[i].rgbRed = palObj->logpalette.palPalEntry[*lpIndex].peRed;
|
||||
lpRGB[i].rgbGreen = palObj->logpalette.palPalEntry[*lpIndex].peGreen;
|
||||
lpRGB[i].rgbBlue = palObj->logpalette.palPalEntry[*lpIndex].peBlue;
|
||||
lpIndex++;
|
||||
}
|
||||
// RELEASEDCINFO(hDC);
|
||||
// RELEASEPALETTEINFO(hPalette);
|
||||
return lpRGB;
|
||||
}
|
||||
|
||||
HPALETTE BuildDIBPalette(BITMAPINFO *bmi, PINT paletteType)
|
||||
{
|
||||
BYTE bits;
|
||||
|
||||
// Determine Bits Per Pixel
|
||||
bits = bmi->bmiHeader.biBitCount;
|
||||
|
||||
// Determine paletteType from Bits Per Pixel
|
||||
if(bits <= 8)
|
||||
{
|
||||
*paletteType = PAL_INDEXED;
|
||||
} else
|
||||
if(bits < 24)
|
||||
{
|
||||
*paletteType = PAL_BITFIELDS;
|
||||
} else {
|
||||
*paletteType = PAL_RGB; // FIXME: This could be BGR, must still check
|
||||
}
|
||||
|
||||
return EngCreatePalette(*paletteType, bmi->bmiHeader.biClrUsed, bmi->bmiColors, 0, 0, 0);
|
||||
}
|
|
@ -77,53 +77,53 @@ W32kRectangle(HDC hDC,
|
|||
int RightRect,
|
||||
int BottomRect)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
PBRUSHOBJ BrushObj;
|
||||
BOOL ret;
|
||||
PRECTL RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
PBRUSHOBJ BrushObj;
|
||||
BOOL ret;
|
||||
PRECTL RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
||||
|
||||
if(!dc) return FALSE;
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
|
||||
} else {
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
|
||||
} else {
|
||||
|
||||
DbgPrint("W32kRectangle pen: ");
|
||||
DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
|
||||
DbgPrint("W32kRectangle pen: ");
|
||||
DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
|
||||
|
||||
BrushObj = PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
|
||||
BrushObj = PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
|
||||
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
LeftRect, TopRect, RightRect, TopRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
LeftRect, TopRect, RightRect, TopRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
RightRect, TopRect, RightRect, BottomRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
RightRect, TopRect, RightRect, BottomRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
LeftRect, BottomRect, RightRect, BottomRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
LeftRect, BottomRect, RightRect, BottomRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
LeftRect, TopRect, LeftRect, BottomRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX */
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj,
|
||||
BrushObj,
|
||||
LeftRect, TopRect, LeftRect, BottomRect,
|
||||
RectBounds, // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX */
|
||||
|
||||
ExFreePool(BrushObj);
|
||||
}
|
||||
ExFreePool(BrushObj);
|
||||
}
|
||||
|
||||
// FIXME: Move current position in DC?
|
||||
|
||||
|
@ -142,5 +142,3 @@ W32kRoundRect(HDC hDC,
|
|||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* GDIOBJ.C - GDI object manipulation routines
|
||||
*
|
||||
* $Id: gdiobj.c,v 1.6 2000/06/16 07:22:39 jfilby Exp $
|
||||
* $Id: gdiobj.c,v 1.7 2001/03/31 15:35:08 jfilby Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -9,23 +9,112 @@
|
|||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <win32k/gdiobj.h>
|
||||
#include <win32k/brush.h>
|
||||
#include <win32k/pen.h>
|
||||
#include <win32k/text.h>
|
||||
|
||||
// GDI stock objects
|
||||
|
||||
static LOGBRUSH WhiteBrush =
|
||||
{ BS_SOLID, RGB(255,255,255), 0 };
|
||||
|
||||
static LOGBRUSH LtGrayBrush =
|
||||
/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
|
||||
{ BS_SOLID, RGB(192,192,192), 0 };
|
||||
|
||||
static LOGBRUSH GrayBrush =
|
||||
/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
|
||||
{ BS_SOLID, RGB(128,128,128), 0 };
|
||||
|
||||
static LOGBRUSH DkGrayBrush =
|
||||
/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
|
||||
/* NB_HATCH_STYLES is an index into HatchBrushes */
|
||||
{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
|
||||
|
||||
static LOGBRUSH BlackBrush =
|
||||
{ BS_SOLID, RGB(0,0,0), 0 };
|
||||
|
||||
static LOGBRUSH NullBrush =
|
||||
{ BS_NULL, 0, 0 };
|
||||
|
||||
static LOGPEN WhitePen =
|
||||
{ PS_SOLID, { 0, 0 }, RGB(255,255,255) };
|
||||
|
||||
static LOGPEN BlackPen =
|
||||
{ PS_SOLID, { 0, 0 }, RGB(0,0,0) };
|
||||
|
||||
static LOGPEN NullPen =
|
||||
{ PS_NULL, { 0, 0 }, 0 };
|
||||
|
||||
static LOGFONT OEMFixedFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
|
||||
|
||||
/* Filler to make the location counter dword aligned again. This is necessary
|
||||
since (a) LOGFONT is packed, (b) gcc places initialised variables in the code
|
||||
segment, and (c) Solaris assembler is stupid. */
|
||||
static UINT align_OEMFixedFont = 1;
|
||||
|
||||
static LOGFONT AnsiFixedFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
|
||||
|
||||
static UINT align_AnsiFixedFont = 1;
|
||||
|
||||
static LOGFONT AnsiVarFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" };
|
||||
|
||||
static UINT align_AnsiVarFont = 1;
|
||||
|
||||
static LOGFONT SystemFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" };
|
||||
|
||||
static UINT align_SystemFont = 1;
|
||||
|
||||
static LOGFONT DeviceDefaultFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" };
|
||||
|
||||
static UINT align_DeviceDefaultFont = 1;
|
||||
|
||||
static LOGFONT SystemFixedFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
|
||||
|
||||
static UINT align_SystemFixedFont = 1;
|
||||
|
||||
/* FIXME: Is this correct? */
|
||||
static LOGFONT DefaultGuiFont =
|
||||
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" };
|
||||
|
||||
static UINT align_DefaultGuiFont = 1;
|
||||
|
||||
static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign
|
||||
// the way handles work, so it's more dynamic now
|
||||
|
||||
HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
|
||||
|
||||
PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic)
|
||||
{
|
||||
PGDIOBJHDR NewObj;
|
||||
|
||||
|
||||
NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
|
||||
|
||||
if (NewObj == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
|
||||
|
||||
NewObj->wMagic = Magic;
|
||||
#if 0
|
||||
KeInitializeSpinlock(&NewObj->Lock);
|
||||
#endif
|
||||
|
||||
|
||||
return (PGDIOBJ)(((PCHAR) NewObj) + sizeof (GDIOBJHDR));
|
||||
}
|
||||
|
||||
|
@ -35,9 +124,9 @@ BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
|
|||
|
||||
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
if (ObjHdr->wMagic != Magic)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ExFreePool (ObjHdr);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -49,9 +138,9 @@ HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
|
|||
if (Obj == NULL) return NULL;
|
||||
objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
if (objHeader->wMagic != Magic)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (HGDIOBJ) objHeader;
|
||||
}
|
||||
|
@ -67,9 +156,9 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
|
|||
/* FIXME: Lock object for duration */
|
||||
|
||||
if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
|
||||
}
|
||||
|
@ -77,7 +166,7 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
|
|||
BOOL GDIOBJ_LockObject (HGDIOBJ Obj)
|
||||
{
|
||||
/* FIXME: write this */
|
||||
return TRUE;
|
||||
// return TRUE;
|
||||
}
|
||||
|
||||
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj)
|
||||
|
@ -92,9 +181,9 @@ HGDIOBJ GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic)
|
|||
|
||||
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
||||
if (objHeader->wMagic != Magic)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return objHeader->hNext;
|
||||
}
|
||||
|
@ -107,14 +196,48 @@ HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj)
|
|||
/* FIXME: should we lock/unlock the object here? */
|
||||
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
||||
if (objHeader->wMagic != Magic)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
oldNext = objHeader->hNext;
|
||||
objHeader->hNext = NextObj;
|
||||
|
||||
return oldNext;
|
||||
}
|
||||
|
||||
VOID CreateStockObjects(void)
|
||||
{
|
||||
// Create GDI Stock Objects from the logical structures we've defined
|
||||
StockObjects[WHITE_BRUSH] = W32kCreateBrushIndirect(&WhiteBrush);
|
||||
StockObjects[LTGRAY_BRUSH] = W32kCreateBrushIndirect(&LtGrayBrush);
|
||||
StockObjects[GRAY_BRUSH] = W32kCreateBrushIndirect(&GrayBrush);
|
||||
StockObjects[DKGRAY_BRUSH] = W32kCreateBrushIndirect(&DkGrayBrush);
|
||||
StockObjects[BLACK_BRUSH] = W32kCreateBrushIndirect(&BlackBrush);
|
||||
StockObjects[NULL_BRUSH] = W32kCreateBrushIndirect(&NullBrush);
|
||||
|
||||
StockObjects[WHITE_PEN] = W32kCreatePenIndirect(&WhitePen);
|
||||
StockObjects[BLACK_PEN] = W32kCreatePenIndirect(&BlackPen);
|
||||
StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen);
|
||||
|
||||
StockObjects[OEM_FIXED_FONT] = W32kCreateFontIndirect(&OEMFixedFont);
|
||||
StockObjects[ANSI_FIXED_FONT] = W32kCreateFontIndirect(&AnsiFixedFont);
|
||||
StockObjects[SYSTEM_FONT] = W32kCreateFontIndirect(&SystemFont);
|
||||
StockObjects[DEVICE_DEFAULT_FONT] = W32kCreateFontIndirect(&DeviceDefaultFont);
|
||||
StockObjects[SYSTEM_FIXED_FONT] = W32kCreateFontIndirect(&SystemFixedFont);
|
||||
StockObjects[DEFAULT_GUI_FONT] = W32kCreateFontIndirect(&DefaultGuiFont);
|
||||
|
||||
StockObjects[DEFAULT_PALETTE] = PALETTE_Init();
|
||||
}
|
||||
|
||||
HGDIOBJ STDCALL W32kGetStockObject(INT Object)
|
||||
{
|
||||
HGDIOBJ ret;
|
||||
|
||||
/* if ((Object < 0) || (Object >= NB_STOCK_OBJECTS)) return 0;
|
||||
if (!StockObjects[Object]) return 0;
|
||||
ret = FIRST_STOCK_HANDLE + Object;
|
||||
|
||||
return ret; */
|
||||
|
||||
return StockObjects[Object]; // FIXME........
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ W32kArc(HDC hDC,
|
|||
int XEndArc,
|
||||
int YEndArc)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
if(!dc) return FALSE;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
||||
XStartArc, YStartArc, XEndArc, YEndArc);
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
||||
XStartArc, YStartArc, XEndArc, YEndArc);
|
||||
|
||||
// EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
|
||||
// XStartArc, YStartArc, XEndArc, YEndArc);
|
||||
|
@ -58,43 +58,43 @@ W32kArcTo(HDC hDC,
|
|||
int XRadial2,
|
||||
int YRadial2)
|
||||
{
|
||||
BOOL result;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
if(!dc) return FALSE;
|
||||
BOOL result;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
if(!dc) return FALSE;
|
||||
|
||||
// Line from current position to starting point of arc
|
||||
W32kLineTo(hDC, XRadial1, YRadial1);
|
||||
// Line from current position to starting point of arc
|
||||
W32kLineTo(hDC, XRadial1, YRadial1);
|
||||
|
||||
// Then the arc is drawn.
|
||||
result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
||||
XRadial1, YRadial1, XRadial2, YRadial2);
|
||||
// Then the arc is drawn.
|
||||
result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
||||
XRadial1, YRadial1, XRadial2, YRadial2);
|
||||
|
||||
// If no error occured, the current position is moved to the ending point of the arc.
|
||||
if(result)
|
||||
{
|
||||
W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
|
||||
}
|
||||
// If no error occured, the current position is moved to the ending point of the arc.
|
||||
if(result)
|
||||
{
|
||||
W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
INT
|
||||
STDCALL
|
||||
W32kGetArcDirection(HDC hDC)
|
||||
{
|
||||
PDC dc;
|
||||
int ret;
|
||||
PDC dc;
|
||||
int ret;
|
||||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = dc->w.ArcDirection;
|
||||
DC_UnlockDC (hDC);
|
||||
ret = dc->w.ArcDirection;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -103,32 +103,28 @@ W32kLineTo(HDC hDC,
|
|||
int XEnd,
|
||||
int YEnd)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
BOOL ret;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
BOOL ret;
|
||||
|
||||
if(!dc) return FALSE;
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
ret = PATH_LineTo(hDC, XEnd, YEnd);
|
||||
} else {
|
||||
if(PATH_IsPathOpen(dc->w.path)) {
|
||||
ret = PATH_LineTo(hDC, XEnd, YEnd);
|
||||
} else {
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj
|
||||
PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)),
|
||||
dc->w.CursPosX, dc->w.CursPosY, XEnd, YEnd,
|
||||
GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC), // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = XEnd;
|
||||
dc->w.CursPosY = YEnd;
|
||||
}
|
||||
|
||||
DbgPrint("W32kLineTo on DC:%08x (h:%08x) with pen handle %08x\n", dc, hDC, dc->w.hPen);
|
||||
DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
|
||||
|
||||
ret = EngLineTo(SurfObj,
|
||||
NULL, // ClipObj
|
||||
PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)),
|
||||
dc->w.CursPosX, dc->w.CursPosY, XEnd, YEnd,
|
||||
GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC), // Bounding rectangle
|
||||
dc->w.ROPmode); // MIX
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = XEnd;
|
||||
dc->w.CursPosY = YEnd;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -138,21 +134,21 @@ W32kMoveToEx(HDC hDC,
|
|||
int Y,
|
||||
LPPOINT Point)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr( hDC );
|
||||
DC *dc = DC_HandleToPtr( hDC );
|
||||
|
||||
if(!dc) return FALSE;
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(Point) {
|
||||
Point->x = dc->w.CursPosX;
|
||||
Point->y = dc->w.CursPosY;
|
||||
}
|
||||
dc->w.CursPosX = X;
|
||||
dc->w.CursPosY = Y;
|
||||
if(Point) {
|
||||
Point->x = dc->w.CursPosX;
|
||||
Point->y = dc->w.CursPosY;
|
||||
}
|
||||
dc->w.CursPosX = X;
|
||||
dc->w.CursPosY = Y;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_MoveTo(hDC);
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_MoveTo(hDC);
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -161,25 +157,25 @@ W32kPolyBezier(HDC hDC,
|
|||
CONST LPPOINT pt,
|
||||
DWORD Count)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
if(!dc) return FALSE;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_PolyBezier(hDC, pt, Count);
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
return PATH_PolyBezier(hDC, pt, Count);
|
||||
|
||||
/* We'll convert it into line segments and draw them using Polyline */
|
||||
{
|
||||
POINT *Pts;
|
||||
INT nOut;
|
||||
BOOL ret;
|
||||
/* We'll convert it into line segments and draw them using Polyline */
|
||||
{
|
||||
POINT *Pts;
|
||||
INT nOut;
|
||||
BOOL ret;
|
||||
|
||||
Pts = GDI_Bezier(pt, Count, &nOut);
|
||||
if(!Pts) return FALSE;
|
||||
DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
|
||||
ret = W32kPolyline(dc->hSelf, Pts, nOut);
|
||||
ExFreePool(Pts);
|
||||
return ret;
|
||||
}
|
||||
Pts = GDI_Bezier(pt, Count, &nOut);
|
||||
if(!Pts) return FALSE;
|
||||
DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
|
||||
ret = W32kPolyline(dc->hSelf, Pts, nOut);
|
||||
ExFreePool(Pts);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -188,28 +184,28 @@ W32kPolyBezierTo(HDC hDC,
|
|||
CONST LPPOINT pt,
|
||||
DWORD Count)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
BOOL ret;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
BOOL ret;
|
||||
|
||||
if(!dc) return FALSE;
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
ret = PATH_PolyBezierTo(hDC, pt, Count);
|
||||
else { /* We'll do it using PolyBezier */
|
||||
POINT *npt;
|
||||
npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
||||
if(!npt) return FALSE;
|
||||
npt[0].x = dc->w.CursPosX;
|
||||
npt[0].y = dc->w.CursPosY;
|
||||
memcpy(npt + 1, pt, sizeof(POINT) * Count);
|
||||
ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
|
||||
ExFreePool(npt);
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = pt[Count-1].x;
|
||||
dc->w.CursPosY = pt[Count-1].y;
|
||||
}
|
||||
return ret;
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
ret = PATH_PolyBezierTo(hDC, pt, Count);
|
||||
else { /* We'll do it using PolyBezier */
|
||||
POINT *npt;
|
||||
npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
||||
if(!npt) return FALSE;
|
||||
npt[0].x = dc->w.CursPosX;
|
||||
npt[0].y = dc->w.CursPosY;
|
||||
memcpy(npt + 1, pt, sizeof(POINT) * Count);
|
||||
ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
|
||||
ExFreePool(npt);
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = pt[Count-1].x;
|
||||
dc->w.CursPosY = pt[Count-1].y;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -237,30 +233,30 @@ W32kPolylineTo(HDC hDC,
|
|||
CONST LPPOINT pt,
|
||||
DWORD Count)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
BOOL ret;
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
BOOL ret;
|
||||
|
||||
if(!dc) return FALSE;
|
||||
if(!dc) return FALSE;
|
||||
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
{
|
||||
ret = PATH_PolylineTo(hDC, pt, Count);
|
||||
}
|
||||
else { /* do it using Polyline */
|
||||
POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
||||
if(!pts) return FALSE;
|
||||
if(PATH_IsPathOpen(dc->w.path))
|
||||
{
|
||||
ret = PATH_PolylineTo(hDC, pt, Count);
|
||||
}
|
||||
else { /* do it using Polyline */
|
||||
POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
||||
if(!pts) return FALSE;
|
||||
|
||||
pts[0].x = dc->w.CursPosX;
|
||||
pts[0].y = dc->w.CursPosY;
|
||||
memcpy( pts + 1, pt, sizeof(POINT) * Count);
|
||||
ret = W32kPolyline(hDC, pts, Count + 1);
|
||||
ExFreePool(pts);
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = pt[Count-1].x;
|
||||
dc->w.CursPosY = pt[Count-1].y;
|
||||
}
|
||||
return ret;
|
||||
pts[0].x = dc->w.CursPosX;
|
||||
pts[0].y = dc->w.CursPosY;
|
||||
memcpy( pts + 1, pt, sizeof(POINT) * Count);
|
||||
ret = W32kPolyline(hDC, pts, Count + 1);
|
||||
ExFreePool(pts);
|
||||
}
|
||||
if(ret) {
|
||||
dc->w.CursPosX = pt[Count-1].x;
|
||||
dc->w.CursPosY = pt[Count-1].y;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -278,22 +274,22 @@ STDCALL
|
|||
W32kSetArcDirection(HDC hDC,
|
||||
int ArcDirection)
|
||||
{
|
||||
PDC dc;
|
||||
INT nOldDirection;
|
||||
PDC dc;
|
||||
INT nOldDirection;
|
||||
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
|
||||
{
|
||||
// SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
dc = DC_HandleToPtr (hDC);
|
||||
if (!dc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
|
||||
{
|
||||
// SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nOldDirection = dc->w.ArcDirection;
|
||||
dc->w.ArcDirection = ArcDirection;
|
||||
nOldDirection = dc->w.ArcDirection;
|
||||
dc->w.ArcDirection = ArcDirection;
|
||||
|
||||
return nOldDirection;
|
||||
return nOldDirection;
|
||||
}
|
||||
|
|
|
@ -15,42 +15,38 @@
|
|||
|
||||
PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
|
||||
{
|
||||
BRUSHOBJ *BrushObj;
|
||||
XLATEOBJ *RGBtoVGA16;
|
||||
BRUSHOBJ *BrushObj;
|
||||
XLATEOBJ *RGBtoVGA16;
|
||||
|
||||
// FIXME: move color translation routines to W32kSelectObject
|
||||
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
|
||||
BrushObj->iSolidColor = pen->logpen.lopnColor;
|
||||
|
||||
DbgPrint("PenToBrushObj:%08x ", pen);
|
||||
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
|
||||
|
||||
RGBtoVGA16 = EngCreateXlate(PAL_INDEXED, PAL_RGB,
|
||||
dc->DevInfo.hpalDefault, NULL);
|
||||
BrushObj->iSolidColor = XLATEOBJ_iXlate(RGBtoVGA16, pen->logpen.lopnColor);
|
||||
|
||||
DbgPrint("BrushObj->iSolidColor:%u\n", BrushObj->iSolidColor);
|
||||
return BrushObj;
|
||||
|
||||
// CreateGDIHandle(BrushGDI, BrushObj);
|
||||
return BrushObj;
|
||||
}
|
||||
|
||||
VOID BitmapToSurf(PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
|
||||
VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
|
||||
{
|
||||
SurfObj->dhsurf = NULL;
|
||||
SurfObj->hsurf = NULL;
|
||||
SurfObj->dhpdev = NULL;
|
||||
SurfObj->hdev = NULL;
|
||||
SurfObj->sizlBitmap = Bitmap->size;
|
||||
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
|
||||
SurfObj->pvBits = Bitmap->bitmap.bmBits;
|
||||
SurfObj->pvScan0 = NULL; // start of bitmap
|
||||
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
|
||||
if(Bitmap->dib)
|
||||
{
|
||||
SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel;
|
||||
SurfObj->lDelta = Bitmap->dib->dsBm.bmWidthBytes;
|
||||
SurfObj->pvBits = Bitmap->dib->dsBm.bmBits;
|
||||
SurfObj->cjBits = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes;
|
||||
} else {
|
||||
SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel;
|
||||
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
|
||||
SurfObj->pvBits = Bitmap->bitmap.bmBits;
|
||||
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
|
||||
}
|
||||
|
||||
SurfObj->dhsurf = NULL;
|
||||
SurfObj->hsurf = NULL;
|
||||
SurfObj->dhpdev = NULL;
|
||||
SurfObj->hdev = NULL;
|
||||
SurfObj->pvScan0 = SurfObj->pvBits; // start of bitmap
|
||||
SurfObj->sizlBitmap = Bitmap->size; // FIXME: alloc memory for our own struct?
|
||||
SurfObj->iUniq = 0; // not sure..
|
||||
SurfObj->iBitmapFormat = BMF_4BPP; /* FIXME */
|
||||
SurfObj->iBitmapFormat = BitmapFormat(SurfGDI->BitsPerPixel, BI_RGB);
|
||||
SurfObj->iType = STYPE_BITMAP;
|
||||
SurfObj->fjBitmap = BMF_TOPDOWN;
|
||||
|
||||
SurfGDI->BytesPerPixel = bytesPerPixel(SurfObj->iType);
|
||||
|
||||
DbgPrint("Bitmap2Surf: cjBits: %u lDelta: %u width: %u height: %u\n",
|
||||
SurfObj->cjBits, SurfObj->lDelta, Bitmap->bitmap.bmWidth, Bitmap->bitmap.bmHeight);
|
||||
}
|
||||
|
|
191
reactos/subsys/win32k/objects/palette.c
Normal file
191
reactos/subsys/win32k/objects/palette.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <win32k/debug.h>
|
||||
#include <win32k/bitmaps.h>
|
||||
#include <win32k/color.h>
|
||||
#include <debug.h>
|
||||
|
||||
static int PALETTE_firstFree = 0;
|
||||
static unsigned char PALETTE_freeList[256];
|
||||
|
||||
int PALETTE_PaletteFlags = 0;
|
||||
PALETTEENTRY *COLOR_sysPal = NULL;
|
||||
int COLOR_gapStart;
|
||||
int COLOR_gapEnd;
|
||||
int COLOR_gapFilled;
|
||||
int COLOR_max;
|
||||
|
||||
PALETTEENTRY *ReturnSystemPalette(void)
|
||||
{
|
||||
return COLOR_sysPal;
|
||||
}
|
||||
|
||||
// Create the system palette
|
||||
HPALETTE PALETTE_Init(void)
|
||||
{
|
||||
int i;
|
||||
HPALETTE hpalette;
|
||||
PLOGPALETTE palPtr;
|
||||
PPALOBJ palObj;
|
||||
const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();
|
||||
|
||||
// create default palette (20 system colors)
|
||||
palPtr = ExAllocatePool(NonPagedPool, sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1) * sizeof(PALETTEENTRY));
|
||||
if (!palPtr) return FALSE;
|
||||
|
||||
palPtr->palVersion = 0x300;
|
||||
palPtr->palNumEntries = NB_RESERVED_COLORS;
|
||||
for(i=0; i<NB_RESERVED_COLORS; i++)
|
||||
{
|
||||
palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
|
||||
palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
|
||||
palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
|
||||
palPtr->palPalEntry[i].peFlags = 0;
|
||||
}
|
||||
hpalette = W32kCreatePalette(palPtr);
|
||||
ExFreePool(palPtr);
|
||||
|
||||
palObj = AccessUserObject(hpalette);
|
||||
if (palObj)
|
||||
{
|
||||
if (!(palObj->mapping = ExAllocatePool(NonPagedPool, sizeof(int) * 20)))
|
||||
{
|
||||
DbgPrint("Win32k: Can not create palette mapping -- out of memory!");
|
||||
return FALSE;
|
||||
}
|
||||
// GDI_ReleaseObj( hpalette );
|
||||
}
|
||||
|
||||
return hpalette;
|
||||
}
|
||||
|
||||
static void PALETTE_FormatSystemPalette(void)
|
||||
{
|
||||
// Build free list so we'd have an easy way to find
|
||||
// out if there are any available colorcells.
|
||||
|
||||
int i, j = PALETTE_firstFree = NB_RESERVED_COLORS/2;
|
||||
|
||||
COLOR_sysPal[j].peFlags = 0;
|
||||
for(i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++)
|
||||
{
|
||||
if( i < COLOR_gapStart || i > COLOR_gapEnd )
|
||||
{
|
||||
COLOR_sysPal[i].peFlags = 0; // unused tag
|
||||
PALETTE_freeList[j] = i; // next
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
PALETTE_freeList[j] = 0;
|
||||
}
|
||||
|
||||
void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
|
||||
{
|
||||
int i = 0;
|
||||
for( ; i<size ; i++ )
|
||||
lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
|
||||
}
|
||||
|
||||
// Set the color-mapping table for selected palette.
|
||||
// Return number of entries which mapping has changed.
|
||||
int PALETTE_SetMapping(PPALOBJ palPtr, UINT uStart, UINT uNum, BOOL mapOnly)
|
||||
{
|
||||
char flag;
|
||||
int prevMapping = (palPtr->mapping) ? 1 : 0;
|
||||
int index, iRemapped = 0;
|
||||
int *mapping;
|
||||
|
||||
// reset dynamic system palette entries
|
||||
|
||||
if( !mapOnly && PALETTE_firstFree != -1) PALETTE_FormatSystemPalette();
|
||||
|
||||
// initialize palette mapping table
|
||||
|
||||
//mapping = HeapReAlloc( GetProcessHeap(), 0, palPtr->mapping,
|
||||
// sizeof(int)*palPtr->logpalette.palNumEntries);
|
||||
ExFreePool(palPtr->mapping);
|
||||
mapping = ExAllocatePool(NonPagedPool, sizeof(int)*palPtr->logpalette.palNumEntries);
|
||||
|
||||
palPtr->mapping = mapping;
|
||||
|
||||
for(uNum += uStart; uStart < uNum; uStart++)
|
||||
{
|
||||
index = -1;
|
||||
flag = PC_SYS_USED;
|
||||
|
||||
switch( palPtr->logpalette.palPalEntry[uStart].peFlags & 0x07 )
|
||||
{
|
||||
case PC_EXPLICIT: // palette entries are indices into system palette
|
||||
// The PC_EXPLICIT flag is used to copy an entry from the system palette into the logical palette
|
||||
index = *(WORD*)(palPtr->logpalette.palPalEntry + uStart);
|
||||
if(index > 255 || (index >= COLOR_gapStart && index <= COLOR_gapEnd))
|
||||
{
|
||||
DbgPrint("Win32k: PC_EXPLICIT: idx %d out of system palette, assuming black.\n", index);
|
||||
index = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PC_RESERVED: // forbid future mappings to this entry
|
||||
// For palette animation, the entries in the logical palette need the PC_RESERVED flag
|
||||
flag |= PC_SYS_RESERVED;
|
||||
|
||||
// fall through
|
||||
default: // try to collapse identical colors
|
||||
index = COLOR_PaletteLookupExactIndex(COLOR_sysPal, 256,
|
||||
*(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
|
||||
// fall through
|
||||
|
||||
case PC_NOCOLLAPSE:
|
||||
// If an entry in the logical palette is marked with the PC_NOCOLLAPSE flag, the palette
|
||||
// manager allocates a free entry in the system palette if one is available and only uses the
|
||||
// closest colour match if there are no (more) free entries in the system palette
|
||||
|
||||
DbgPrint("Win32k: WARNING: PC_NOCOLLAPSE is not yet working properly\n");
|
||||
|
||||
if( index < 0 )
|
||||
{
|
||||
if(PALETTE_firstFree > 0 /* && !(PALETTE_PaletteFlags & PALETTE_FIXED) FIXME */ )
|
||||
{
|
||||
DgPrint("Win32k: Unimplemented Palette Operation: PC_NOCOLLAPSE [objects/palette.c]\n");
|
||||
/* XColor color;
|
||||
index = PALETTE_firstFree; // ought to be available
|
||||
PALETTE_firstFree = PALETTE_freeList[index];
|
||||
|
||||
color.pixel = (PALETTE_PaletteToXPixel) ? PALETTE_PaletteToXPixel[index] : index;
|
||||
color.red = palPtr->logpalette.palPalEntry[uStart].peRed << 8;
|
||||
color.green = palPtr->logpalette.palPalEntry[uStart].peGreen << 8;
|
||||
color.blue = palPtr->logpalette.palPalEntry[uStart].peBlue << 8;
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
TSXStoreColor(display, PALETTE_PaletteXColormap, &color);
|
||||
|
||||
COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[uStart];
|
||||
COLOR_sysPal[index].peFlags = flag;
|
||||
PALETTE_freeList[index] = 0;
|
||||
|
||||
if(PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; */
|
||||
break;
|
||||
}
|
||||
/* else if (PALETTE_PaletteFlags & PALETTE_VIRTUAL)
|
||||
{
|
||||
index = PALETTE_ToPhysical(NULL, 0x00ffffff &
|
||||
*(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
|
||||
break;
|
||||
} FIXME */
|
||||
|
||||
// we have to map to existing entry in the system palette
|
||||
|
||||
index = COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL,
|
||||
*(COLORREF*)(palPtr->logpalette.palPalEntry + uStart), TRUE);
|
||||
}
|
||||
palPtr->logpalette.palPalEntry[uStart].peFlags |= PC_SYS_USED;
|
||||
|
||||
/* if(PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; FIXME */
|
||||
break;
|
||||
}
|
||||
|
||||
if( !prevMapping || palPtr->mapping[uStart] != index ) iRemapped++;
|
||||
palPtr->mapping[uStart] = index;
|
||||
|
||||
}
|
||||
return iRemapped;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
@ -12,37 +10,37 @@ HPEN
|
|||
STDCALL
|
||||
W32kCreatePen(INT PenStyle, INT Width, COLORREF Color)
|
||||
{
|
||||
LOGPEN logpen;
|
||||
LOGPEN logpen;
|
||||
|
||||
logpen.lopnStyle = PenStyle;
|
||||
logpen.lopnWidth.x = Width;
|
||||
logpen.lopnWidth.y = 0;
|
||||
logpen.lopnColor = Color;
|
||||
logpen.lopnStyle = PenStyle;
|
||||
logpen.lopnWidth.x = Width;
|
||||
logpen.lopnWidth.y = 0;
|
||||
logpen.lopnColor = Color;
|
||||
|
||||
return W32kCreatePenIndirect(&logpen);
|
||||
return W32kCreatePenIndirect(&logpen);
|
||||
}
|
||||
|
||||
HPEN
|
||||
STDCALL
|
||||
W32kCreatePenIndirect(CONST PLOGPEN lgpn)
|
||||
{
|
||||
PPENOBJ penPtr;
|
||||
HPEN hpen;
|
||||
PPENOBJ penPtr;
|
||||
HPEN hpen;
|
||||
|
||||
if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
|
||||
if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
|
||||
|
||||
penPtr = PENOBJ_AllocPen();
|
||||
hpen = PENOBJ_PtrToHandle(penPtr);
|
||||
if (!hpen) return 0;
|
||||
PENOBJ_LockPen(hpen);
|
||||
penPtr = PENOBJ_AllocPen();
|
||||
hpen = PENOBJ_PtrToHandle(penPtr);
|
||||
if (!hpen) return 0;
|
||||
PENOBJ_LockPen(hpen);
|
||||
|
||||
penPtr->logpen.lopnStyle = lgpn->lopnStyle;
|
||||
penPtr->logpen.lopnWidth = lgpn->lopnWidth;
|
||||
penPtr->logpen.lopnColor = lgpn->lopnColor;
|
||||
penPtr->logpen.lopnStyle = lgpn->lopnStyle;
|
||||
penPtr->logpen.lopnWidth = lgpn->lopnWidth;
|
||||
penPtr->logpen.lopnColor = lgpn->lopnColor;
|
||||
|
||||
PENOBJ_UnlockPen(hpen);
|
||||
PENOBJ_UnlockPen(hpen);
|
||||
|
||||
return hpen;
|
||||
return hpen;
|
||||
}
|
||||
|
||||
HPEN
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
|
|
@ -6,10 +6,24 @@
|
|||
#include <win32k/dc.h>
|
||||
#include <win32k/text.h>
|
||||
#include <win32k/kapi.h>
|
||||
#include <freetype/freetype.h>
|
||||
|
||||
// #define NDEBUG
|
||||
#include <win32k/debug1.h>
|
||||
|
||||
FT_Library library;
|
||||
|
||||
BOOL InitFontSupport()
|
||||
{
|
||||
ULONG error;
|
||||
|
||||
error = FT_Init_FreeType(&library);
|
||||
if(error)
|
||||
{
|
||||
return FALSE;
|
||||
} else return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
STDCALL
|
||||
W32kAddFontResource(LPCWSTR Filename)
|
||||
|
@ -41,7 +55,7 @@ HFONT
|
|||
STDCALL
|
||||
W32kCreateFontIndirect(CONST LPLOGFONT lf)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
DbgPrint("WARNING: W32kCreateFontIndirect is current unimplemented\n");
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -336,9 +350,9 @@ W32kSetTextColor(HDC hDC,
|
|||
PDC dc = DC_HandleToPtr(hDC);
|
||||
|
||||
if (!dc)
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
|
||||
oldColor = dc->w.textColor;
|
||||
dc->w.textColor = color;
|
||||
|
@ -364,19 +378,176 @@ W32kTextOut(HDC hDC,
|
|||
LPCWSTR String,
|
||||
int Count)
|
||||
{
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
UNICODE_STRING UString;
|
||||
ANSI_STRING AString;
|
||||
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
||||
|
||||
RtlCreateUnicodeString(&UString, (PWSTR)String);
|
||||
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
UNICODE_STRING FileName;
|
||||
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j;
|
||||
FT_Face face;
|
||||
FT_GlyphSlot glyph;
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||
PVOID buffer;
|
||||
ULONG size, TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 5, StringLength;
|
||||
FT_Vector origin;
|
||||
FT_Bitmap bit, bit2, bit3;
|
||||
POINTL SourcePoint;
|
||||
RECTL DestRect;
|
||||
HBITMAP HSourceGlyph;
|
||||
PSURFOBJ SourceGlyphSurf;
|
||||
SIZEL bitSize;
|
||||
FT_CharMap found = 0;
|
||||
FT_CharMap charmap;
|
||||
PCHAR bitbuf;
|
||||
|
||||
// For now we're just going to use an internal font
|
||||
grWriteCellString(SurfObj, XStart, YStart, AString.Buffer, 0xffffff);
|
||||
// For now we're just going to use an internal font
|
||||
// grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
|
||||
|
||||
RtlFreeAnsiString(&AString);
|
||||
RtlFreeUnicodeString(&UString);
|
||||
// Prepare the Unicode FileName
|
||||
RtlCreateUnicodeString(&FileName, L"\\SystemRoot\\fonts\\arial.ttf");
|
||||
|
||||
// Open the Module
|
||||
InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
|
||||
|
||||
Status = NtOpenFile(&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, NULL, 0, 0);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("Could not open module file: %wZ\n", L"c:/reactos/fonts/arial.ttf");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the size of the file
|
||||
Status = NtQueryInformationFile(FileHandle, NULL, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("Could not get file size\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate nonpageable memory for driver
|
||||
size = FileStdInfo.EndOfFile.u.LowPart;
|
||||
buffer = ExAllocatePool(NonPagedPool, size);
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
DbgPrint("could not allocate memory for module");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load driver into memory chunk
|
||||
Status = NtReadFile(FileHandle, 0, 0, 0, 0, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("could not read module file into memory");
|
||||
ExFreePool(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NtClose(FileHandle);
|
||||
|
||||
error = FT_New_Memory_Face(library,
|
||||
buffer, // first byte in memory
|
||||
size, // size in bytes
|
||||
0, // face_index
|
||||
&face );
|
||||
if ( error == FT_Err_Unknown_File_Format )
|
||||
{
|
||||
DbgPrint("Unknown font file format\n");
|
||||
}
|
||||
else if ( error )
|
||||
{
|
||||
DbgPrint("Error reading font file\n");
|
||||
}
|
||||
|
||||
DbgPrint("Family name: %s\n", face->family_name);
|
||||
DbgPrint("Style name: %s\n", face->style_name);
|
||||
DbgPrint("Num glyphs: %u\n", face->num_glyphs);
|
||||
DbgPrint("Height: %d\n", face->height);
|
||||
|
||||
if (face->charmap == NULL)
|
||||
{
|
||||
DbgPrint("WARNING: No charmap selected!\n");
|
||||
DbgPrint("This font face has %d charmaps\n", face->num_charmaps);
|
||||
|
||||
for ( n = 0; n < face->num_charmaps; n++ )
|
||||
{
|
||||
charmap = face->charmaps[n];
|
||||
DbgPrint("found charmap encoding: %u\n", charmap->encoding);
|
||||
if (charmap->encoding != 0)
|
||||
{
|
||||
found = charmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) DbgPrint("WARNING: Could not find desired charmap!\n");
|
||||
|
||||
error = FT_Set_Charmap(face, found);
|
||||
if (error) DbgPrint("WARNING: Could not set the charmap!\n");
|
||||
|
||||
error = FT_Set_Char_Size(
|
||||
face, // handle to face object
|
||||
16*64, // char_width in 1/64th of points
|
||||
16*64, // char_height in 1/64th of points
|
||||
300, // horizontal device resolution
|
||||
300 ); // vertical device resolution
|
||||
|
||||
StringLength = wcslen(String);
|
||||
DbgPrint("StringLength: %u\n", StringLength);
|
||||
|
||||
for(i=0; i<StringLength; i++)
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index(face, *String);
|
||||
|
||||
error = FT_Load_Glyph(
|
||||
face, // handle to face object
|
||||
glyph_index, // glyph index
|
||||
FT_LOAD_DEFAULT ); // load flags (erase previous glyph)
|
||||
if(error) DbgPrint("WARNING: Failed to load and render glyph!\n");
|
||||
|
||||
glyph = face->glyph;
|
||||
|
||||
if ( glyph->format == ft_glyph_format_outline )
|
||||
{
|
||||
DbgPrint("Outline Format Font\n");
|
||||
error = FT_Render_Glyph( glyph, ft_render_mode_normal );
|
||||
if(error) DbgPrint("WARNING: Failed to render glyph!\n");
|
||||
} else {
|
||||
DbgPrint("Bitmap Format Font\n");
|
||||
bit3.rows = glyph->bitmap.rows;
|
||||
bit3.width = glyph->bitmap.width;
|
||||
bit3.pitch = glyph->bitmap.pitch;
|
||||
bit3.buffer = glyph->bitmap.buffer;
|
||||
}
|
||||
|
||||
SourcePoint.x = 0;
|
||||
SourcePoint.y = 0;
|
||||
DestRect.left = TextLeft;
|
||||
DestRect.top = TextTop;
|
||||
DestRect.right = TextLeft + glyph->bitmap.width-1;
|
||||
DestRect.bottom = TextTop + glyph->bitmap.rows-1;
|
||||
bitSize.cx = glyph->bitmap.width-1;
|
||||
bitSize.cy = glyph->bitmap.rows-1;
|
||||
|
||||
HSourceGlyph = EngCreateBitmap(bitSize, glyph->bitmap.pitch /* -1 */ , BMF_8BPP, 0, glyph->bitmap.buffer);
|
||||
SourceGlyphSurf = AccessUserObject(HSourceGlyph);
|
||||
|
||||
EngBitBlt(SurfObj, SourceGlyphSurf,
|
||||
NULL, NULL, NULL, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
|
||||
|
||||
TextLeft += glyph->bitmap.width + SpaceBetweenChars;
|
||||
String++;
|
||||
}
|
||||
|
||||
DbgPrint("BREAK\n"); for (;;) ;
|
||||
|
||||
/* RtlFreeAnsiString(AString);
|
||||
RtlFreeUnicodeString(UString); */
|
||||
}
|
||||
|
||||
UINT
|
||||
|
@ -387,4 +558,3 @@ W32kTranslateCharsetInfo(PDWORD Src,
|
|||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue