mirror of
https://github.com/reactos/reactos.git
synced 2025-07-24 17:53:43 +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 "enum.h"
|
||||||
#include "objects.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)
|
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->left = max(prcSrc1->left, prcSrc2->left);
|
||||||
prcDst->right = min(prcSrc1->right, prcSrc2->right);
|
prcDst->right = min(prcSrc1->right, prcSrc2->right);
|
||||||
|
|
||||||
if (prcDst->left < prcDst->right)
|
if (prcDst->left < prcDst->right)
|
||||||
{
|
{
|
||||||
prcDst->top = max(prcSrc1->top, prcSrc2->top);
|
prcDst->top = max(prcSrc1->top, prcSrc2->top);
|
||||||
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
|
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
|
||||||
|
|
||||||
if (prcDst->top < prcDst->bottom)
|
if (prcDst->top < prcDst->bottom) return(TRUE);
|
||||||
return(TRUE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*prcDst = rclEmpty;
|
*prcDst = rclEmpty;
|
||||||
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
||||||
SURFOBJ *Mask, CLIPOBJ *ClipRegion,
|
SURFOBJ *Mask, CLIPOBJ *ClipRegion,
|
||||||
XLATEOBJ *ColorTranslation, RECTL *DestRect,
|
XLATEOBJ *ColorTranslation, RECTL *DestRect,
|
||||||
POINTL *SourcePoint, POINTL *MaskRect,
|
POINTL *SourcePoint, POINTL *MaskRect,
|
||||||
BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4)
|
BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4)
|
||||||
{
|
{
|
||||||
BYTE clippingType;
|
BYTE clippingType;
|
||||||
RECTL rclTmp;
|
RECTL rclTmp;
|
||||||
POINTL ptlTmp;
|
POINTL ptlTmp;
|
||||||
RECT_ENUM RectEnum;
|
RECT_ENUM RectEnum;
|
||||||
BOOL EnumMore;
|
BOOL EnumMore;
|
||||||
SURFGDI *DestGDI, *SourceGDI;
|
PSURFGDI DestGDI, SourceGDI;
|
||||||
BOOLEAN canCopyBits;
|
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
|
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||||
// if it exists
|
|
||||||
if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
|
|
||||||
(BrushOrigin == NULL) && (rop4 == 0) )
|
|
||||||
{
|
|
||||||
canCopyBits = TRUE;
|
|
||||||
} else
|
|
||||||
canCopyBits = FALSE;
|
|
||||||
|
|
||||||
// FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's
|
// If we don't have to do anything special, we can punt to DrvCopyBits
|
||||||
// format. Call DrvDitherColor function where necessary and if available
|
// 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
|
// Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
|
||||||
// punt to EngCopyBits and not the driver's DrvCopyBits just yet so
|
// * The destination bitmap is not managed by the GDI OR
|
||||||
// that the EngCopyBits can take care of the clipping drivers
|
if(Dest->iType != STYPE_BITMAP)
|
||||||
// DrvCopyBits
|
{
|
||||||
|
// Destination surface is device managed
|
||||||
|
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||||
|
|
||||||
// FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd
|
if (DestGDI->BitBlt!=NULL)
|
||||||
// function to go there instead of the Engine's bltting function
|
{
|
||||||
// so as to do the clipping for the driver
|
// 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
|
hTemp = EngCreateBitmap(TempSize,
|
||||||
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
|
||||||
{
|
Dest->iBitmapFormat, 0, NULL);
|
||||||
// Destination surface is device managed
|
TempSurf = AccessUserObject(hTemp);
|
||||||
if(Dest->iType!=STYPE_BITMAP)
|
|
||||||
{
|
|
||||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
|
||||||
|
|
||||||
if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
|
// 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);
|
||||||
return DestGDI->CopyBits(Dest, Source, ClipRegion,
|
|
||||||
ColorTranslation, DestRect, SourcePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DestGDI->BitBlt!=NULL)
|
return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
|
||||||
{
|
NULL, DestRect, &TempPoint,
|
||||||
return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion,
|
MaskRect, Brush, BrushOrigin, rop4);
|
||||||
ColorTranslation, DestRect, SourcePoint,
|
}
|
||||||
MaskRect, Brush, BrushOrigin, rop4);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Source surface is device managed
|
// * 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)
|
if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
|
||||||
{
|
{
|
||||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
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))
|
// Convert the surface from the driver into the required destination surface
|
||||||
{
|
}
|
||||||
return SourceGDI->CopyBits(Dest, Source, ClipRegion,
|
}
|
||||||
ColorTranslation, DestRect, SourcePoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SourceGDI->BitBlt!=NULL)
|
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||||
{
|
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||||
return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
|
|
||||||
ColorTranslation, DestRect, SourcePoint,
|
|
||||||
MaskRect, Brush, BrushOrigin, rop4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 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
|
// We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
|
||||||
// should take care of it
|
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);
|
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
|
||||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
||||||
|
|
||||||
// Determine clipping type
|
return(TRUE);
|
||||||
if (ClipRegion == (CLIPOBJ *) NULL)
|
|
||||||
{
|
|
||||||
clippingType = DC_TRIVIAL;
|
|
||||||
} else {
|
|
||||||
clippingType = ClipRegion->iDComplexity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't handle color translation just yet
|
case DC_COMPLEX:
|
||||||
|
|
||||||
if ((rop4 == 0x0000CCCC) &&
|
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||||
((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
|
|
||||||
{
|
|
||||||
switch(clippingType)
|
|
||||||
{
|
|
||||||
case DC_TRIVIAL:
|
|
||||||
BitBltCopy(Dest, Source,
|
|
||||||
DestGDI, SourceGDI,
|
|
||||||
DestRect, SourcePoint, Source->lDelta);
|
|
||||||
|
|
||||||
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;
|
prcl++;
|
||||||
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
|
||||||
|
|
||||||
BitBltCopy(Dest, Source,
|
} while (prcl < prclEnd);
|
||||||
DestGDI, SourceGDI,
|
}
|
||||||
&rclTmp, &ptlTmp, Source->lDelta);
|
|
||||||
|
|
||||||
return(TRUE);
|
} while(EnumMore);
|
||||||
|
|
||||||
case DC_COMPLEX:
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES,
|
return(FALSE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
PVOID BRUSHOBJ_pvAllocRbrush(IN PBRUSHOBJ BrushObj,
|
PVOID BRUSHOBJ_pvAllocRbrush(IN PBRUSHOBJ BrushObj,
|
||||||
IN ULONG ObjSize)
|
IN ULONG ObjSize)
|
||||||
{
|
{
|
||||||
BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
|
BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
|
||||||
return BrushObj->pvRbrush;
|
return BrushObj->pvRbrush;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID BRUSHOBJ_pvGetRbrush(IN PBRUSHOBJ BrushObj)
|
PVOID BRUSHOBJ_pvGetRbrush(IN PBRUSHOBJ BrushObj)
|
||||||
{
|
{
|
||||||
return BrushObj->pvRbrush;
|
return BrushObj->pvRbrush;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
typedef struct _BRUSHINST
|
typedef struct _BRUSHINST
|
||||||
{
|
{
|
||||||
// We need to removed ajC0-3 when color pattern code is complete!!!
|
// We need to removed ajC0-3 when color pattern code is complete!!!
|
||||||
//
|
//
|
||||||
BYTE ajC0[8]; // Color bits for plane 0
|
BYTE ajC0[8]; // Color bits for plane 0
|
||||||
BYTE ajC1[8]; // Color bits for plane 1
|
BYTE ajC1[8]; // Color bits for plane 1
|
||||||
BYTE ajC2[8]; // Color bits for plane 2
|
BYTE ajC2[8]; // Color bits for plane 2
|
||||||
BYTE ajC3[8]; // Color bits for plane 3
|
BYTE ajC3[8]; // Color bits for plane 3
|
||||||
|
|
||||||
BYTE ajPattern[32]; // Color bits for the mask
|
BYTE ajPattern[32]; // Color bits for the mask
|
||||||
USHORT usStyle; // Brush style
|
USHORT usStyle; // Brush style
|
||||||
BYTE fjAccel; // Accelerator flags
|
BYTE fjAccel; // Accelerator flags
|
||||||
BYTE jFgColor; // Current foreground color
|
BYTE jFgColor; // Current foreground color
|
||||||
BYTE jBkColor; // Current background color
|
BYTE jBkColor; // Current background color
|
||||||
BYTE RealWidth;//
|
BYTE RealWidth;//
|
||||||
BYTE YShiftValue; //
|
BYTE YShiftValue; //
|
||||||
BYTE jOldBrushRealized; //
|
BYTE jOldBrushRealized; //
|
||||||
DWORD Width; // Width of brush
|
DWORD Width; // Width of brush
|
||||||
DWORD Height;
|
DWORD Height;
|
||||||
BYTE *pPattern; //Pointer to realized mono pattern
|
BYTE *pPattern; //Pointer to realized mono pattern
|
||||||
} BRUSHINST;
|
} BRUSHINST;
|
||||||
|
|
||||||
#define BRI_SOLID 0
|
#define BRI_SOLID 0
|
||||||
|
|
|
@ -18,109 +18,109 @@
|
||||||
CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
|
CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
|
||||||
ULONG Mode, ULONG Options)
|
ULONG Mode, ULONG Options)
|
||||||
{
|
{
|
||||||
HCLIP NewClip;
|
HCLIP NewClip;
|
||||||
CLIPOBJ *ClipObj;
|
CLIPOBJ *ClipObj;
|
||||||
CLIPGDI *ClipGDI;
|
CLIPGDI *ClipGDI;
|
||||||
|
|
||||||
ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
||||||
ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
|
ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
|
||||||
|
|
||||||
NewClip = CreateGDIHandle(ClipGDI, ClipObj);
|
NewClip = CreateGDIHandle(ClipGDI, ClipObj);
|
||||||
|
|
||||||
ClipGDI->NumRegionRects = NumRects;
|
ClipGDI->NumRegionRects = NumRects;
|
||||||
ClipGDI->RegionRects = Rects;
|
ClipGDI->RegionRects = Rects;
|
||||||
ClipObj->iMode = Mode;
|
ClipObj->iMode = Mode;
|
||||||
ClipObj->fjOptions = Options;
|
ClipObj->fjOptions = Options;
|
||||||
ClipObj->iDComplexity = DC_TRIVIAL;
|
ClipObj->iDComplexity = DC_TRIVIAL;
|
||||||
|
|
||||||
if(NumRects == 1)
|
if(NumRects == 1)
|
||||||
{
|
{
|
||||||
ClipObj->iFComplexity = FC_RECT;
|
ClipObj->iFComplexity = FC_RECT;
|
||||||
ClipObj->iDComplexity = DC_RECT;
|
ClipObj->iDComplexity = DC_RECT;
|
||||||
|
|
||||||
// FIXME: Is this correct??
|
// FIXME: Is this correct??
|
||||||
ClipObj->rclBounds = Rects[0];
|
ClipObj->rclBounds = Rects[0];
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ClipObj->iDComplexity = DC_COMPLEX;
|
ClipObj->iDComplexity = DC_COMPLEX;
|
||||||
if(NumRects <= 4)
|
if(NumRects <= 4)
|
||||||
{
|
{
|
||||||
ClipObj->iFComplexity = FC_RECT4;
|
ClipObj->iFComplexity = FC_RECT4;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ClipObj->iFComplexity = FC_COMPLEX;
|
ClipObj->iFComplexity = FC_COMPLEX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClipObj;
|
return ClipObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)
|
VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)
|
||||||
{
|
{
|
||||||
HCLIP HClip = AccessHandleFromUserObject(ClipObj);
|
HCLIP HClip = AccessHandleFromUserObject(ClipObj);
|
||||||
CLIPGDI *ClipGDI = AccessInternalObject(HClip);
|
CLIPGDI *ClipGDI = AccessInternalObject(HClip);
|
||||||
|
|
||||||
EngFreeMem(ClipGDI);
|
EngFreeMem(ClipGDI);
|
||||||
EngFreeMem(ClipObj);
|
EngFreeMem(ClipObj);
|
||||||
FreeGDIHandle(HClip);
|
FreeGDIHandle(HClip);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects)
|
VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects)
|
||||||
{
|
{
|
||||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||||
|
|
||||||
ClipGDI->NumIntersectRects = NumRects;
|
ClipGDI->NumIntersectRects = NumRects;
|
||||||
ClipGDI->IntersectRects = IntersectRects;
|
ClipGDI->IntersectRects = IntersectRects;
|
||||||
|
|
||||||
if(NumRects == 1)
|
if(NumRects == 1)
|
||||||
{
|
{
|
||||||
ClipObj->iDComplexity = DC_RECT;
|
ClipObj->iDComplexity = DC_RECT;
|
||||||
ClipObj->rclBounds = IntersectRects[0];
|
ClipObj->rclBounds = IntersectRects[0];
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ClipObj->iDComplexity = DC_COMPLEX;
|
ClipObj->iDComplexity = DC_COMPLEX;
|
||||||
ClipGDI->IntersectRects = IntersectRects;
|
ClipGDI->IntersectRects = IntersectRects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLIPOBJ *EngCreateClip(VOID)
|
CLIPOBJ *EngCreateClip(VOID)
|
||||||
{
|
{
|
||||||
return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID EngDeleteClip(CLIPOBJ *ClipRegion)
|
VOID EngDeleteClip(CLIPOBJ *ClipRegion)
|
||||||
{
|
{
|
||||||
EngFreeMem(ClipRegion);
|
EngFreeMem(ClipRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj, IN BOOL ShouldDoAll,
|
ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj, IN BOOL ShouldDoAll,
|
||||||
IN ULONG ClipType, IN ULONG BuildOrder,
|
IN ULONG ClipType, IN ULONG BuildOrder,
|
||||||
IN ULONG MaxRects)
|
IN ULONG MaxRects)
|
||||||
{
|
{
|
||||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||||
|
|
||||||
ClipGDI->EnumPos = 0;
|
ClipGDI->EnumPos = 0;
|
||||||
ClipGDI->EnumRects.c = MaxRects;
|
ClipGDI->EnumRects.c = MaxRects;
|
||||||
|
|
||||||
// Return the number of rectangles enumerated
|
// Return the number of rectangles enumerated
|
||||||
if(ClipGDI->EnumRects.c>MaxRects)
|
if(ClipGDI->EnumRects.c>MaxRects)
|
||||||
{
|
{
|
||||||
ClipGDI->EnumRects.c = 0xFFFFFFFF;
|
ClipGDI->EnumRects.c = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClipGDI->EnumRects.c;
|
return ClipGDI->EnumRects.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize,
|
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize,
|
||||||
OUT ULONG *EnumRects)
|
OUT ULONG *EnumRects)
|
||||||
{
|
{
|
||||||
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
|
||||||
|
|
||||||
ClipGDI->EnumPos++;
|
ClipGDI->EnumPos++;
|
||||||
|
|
||||||
if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
|
if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else
|
} else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,192 +11,153 @@
|
||||||
#include <ddk/winddi.h>
|
#include <ddk/winddi.h>
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "enum.h"
|
#include "enum.h"
|
||||||
|
#include "../dib/dib.h"
|
||||||
|
|
||||||
VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
SURFGDI *DestGDI, SURFGDI *SourceGDI,
|
||||||
PRECTL DestRect, POINTL *SourcePoint,
|
PRECTL DestRect, POINTL *SourcePoint,
|
||||||
ULONG Delta, XLATEOBJ *ColorTranslation)
|
ULONG Delta, XLATEOBJ *ColorTranslation)
|
||||||
{
|
{
|
||||||
ULONG dy, leftOfSource, leftOfDest, Width, SourceBPP, DestBPP, RGBulong = 0, idxColor, i, TrivialCopy = 0;
|
ULONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel;
|
||||||
BYTE *SourcePos, *SourceInitial, *DestPos, *DestInitial;
|
|
||||||
|
|
||||||
// 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)
|
DestWidth = DestRect->right - DestRect->left;
|
||||||
{
|
DestHeight = DestRect->bottom - DestRect->top;
|
||||||
TrivialCopy = 1;
|
CurrentSourceCol = SourcePoint->x;
|
||||||
} else if(ColorTranslation->flXlate & XO_TRIVIAL)
|
CurrentSourceLine = SourcePoint->y;
|
||||||
{
|
|
||||||
TrivialCopy = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
|
// Assign GetPixel DIB function according to bytes per pixel
|
||||||
leftOfDest = DestRect->left * DestGDI->BytesPerPixel;
|
switch(DestGDI->BitsPerPixel)
|
||||||
Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
|
{
|
||||||
|
case 4:
|
||||||
|
return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
|
||||||
|
DestRect, SourcePoint, Delta, ColorTranslation);
|
||||||
|
break;
|
||||||
|
|
||||||
if(TrivialCopy == 1)
|
case 24:
|
||||||
{
|
return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
|
||||||
for(dy=DestRect->top; dy<DestRect->bottom; dy++)
|
DestRect, SourcePoint, Delta, ColorTranslation);
|
||||||
{
|
break;
|
||||||
memcpy(DestSurf->pvBits+Delta*dy+leftOfDest,
|
|
||||||
SourceSurf->pvBits+Delta*dy+leftOfSource,
|
|
||||||
Width);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
if(ColorTranslation->flXlate & XO_TABLE)
|
|
||||||
{
|
|
||||||
SourceBPP = bytesPerPixel(SourceSurf->iBitmapFormat);
|
|
||||||
DestBPP = bytesPerPixel(DestSurf->iBitmapFormat);
|
|
||||||
|
|
||||||
SourcePos = SourceSurf->pvBits +
|
default:
|
||||||
(SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP);
|
return FALSE;
|
||||||
SourceInitial = SourcePos;
|
}
|
||||||
|
|
||||||
DestPos = DestSurf->pvBits +
|
return TRUE;
|
||||||
((DestRect->bottom - DestRect->top) * DestSurf->lDelta) + (DestRect->left * DestBPP);
|
|
||||||
DestInitial = DestPos;
|
|
||||||
|
|
||||||
for(i=DestRect->left; i<DestRect->right; i++)
|
|
||||||
{
|
|
||||||
memcpy(&RGBulong, SourcePos, SourceBPP);
|
|
||||||
idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong);
|
|
||||||
memcpy(DestPos, &idxColor, DestBPP);
|
|
||||||
|
|
||||||
SourcePos+=SourceBPP;
|
|
||||||
DestPos+=DestBPP;
|
|
||||||
}
|
|
||||||
SourcePos = SourceInitial + SourceSurf->lDelta;
|
|
||||||
DestPos = DestInitial + DestSurf->lDelta;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
|
||||||
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
|
||||||
RECTL *DestRect, POINTL *SourcePoint)
|
RECTL *DestRect, POINTL *SourcePoint)
|
||||||
{
|
{
|
||||||
SURFGDI *DestGDI, *SourceGDI;
|
SURFGDI *DestGDI, *SourceGDI;
|
||||||
BYTE clippingType;
|
BYTE clippingType;
|
||||||
RECTL rclTmp;
|
RECTL rclTmp;
|
||||||
POINTL ptlTmp;
|
POINTL ptlTmp;
|
||||||
RECT_ENUM RectEnum;
|
RECT_ENUM RectEnum;
|
||||||
BOOL EnumMore;
|
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,
|
// If one of the surfaces isn't managed by the GDI
|
||||||
// mark the copy block function to be DrvCopyBits instead of the
|
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
||||||
// GDI's copy bit function so as to remove clipping from the
|
{
|
||||||
// driver's responsibility
|
// 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 (DestGDI->CopyBits!=NULL)
|
||||||
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
|
|
||||||
{
|
|
||||||
|
|
||||||
// Destination surface is device managed
|
|
||||||
if(Dest->iType!=STYPE_BITMAP)
|
|
||||||
{
|
{
|
||||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
return DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
|
||||||
|
|
||||||
if (DestGDI->CopyBits!=NULL)
|
|
||||||
{
|
|
||||||
return DestGDI->CopyBits(Dest, Source, Clip,
|
|
||||||
ColorTranslation, DestRect, SourcePoint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Source surface is device managed
|
// Source surface is device managed
|
||||||
if(Source->iType!=STYPE_BITMAP)
|
if(Source->iType!=STYPE_BITMAP)
|
||||||
|
{
|
||||||
|
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
||||||
|
|
||||||
|
if (SourceGDI->CopyBits!=NULL)
|
||||||
{
|
{
|
||||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
return SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
|
||||||
|
|
||||||
if (SourceGDI->CopyBits!=NULL)
|
|
||||||
{
|
|
||||||
return SourceGDI->CopyBits(Dest, Source, Clip,
|
|
||||||
ColorTranslation, DestRect, SourcePoint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If CopyBits wasn't hooked, BitBlt must be
|
// If CopyBits wasn't hooked, BitBlt must be
|
||||||
return EngBitBlt(Dest, Source,
|
return EngBitBlt(Dest, Source,
|
||||||
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
|
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine clipping type
|
// Determine clipping type
|
||||||
if (Clip == (CLIPOBJ *) NULL)
|
if (Clip == (CLIPOBJ *) NULL)
|
||||||
{
|
{
|
||||||
clippingType = DC_TRIVIAL;
|
clippingType = DC_TRIVIAL;
|
||||||
} else {
|
} else {
|
||||||
clippingType = Clip->iDComplexity;
|
clippingType = Clip->iDComplexity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only handle XO_TABLE translations at the momement
|
// We only handle XO_TABLE translations at the momement
|
||||||
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
|
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
|
||||||
(ColorTranslation->flXlate & XO_TABLE))
|
(ColorTranslation->flXlate & XO_TABLE))
|
||||||
{
|
{
|
||||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
||||||
DestGDI = AccessInternalObjectFromUserObject(Dest);
|
DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
|
||||||
|
|
||||||
switch(clippingType)
|
switch(clippingType)
|
||||||
{
|
{
|
||||||
case DC_TRIVIAL:
|
case DC_TRIVIAL:
|
||||||
CopyBitsCopy(Dest, Source,
|
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
||||||
DestGDI, SourceGDI,
|
return(TRUE);
|
||||||
DestRect, SourcePoint, Source->lDelta, ColorTranslation);
|
|
||||||
|
|
||||||
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;
|
case DC_COMPLEX:
|
||||||
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
|
|
||||||
|
|
||||||
CopyBitsCopy(Dest, Source,
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
|
||||||
DestGDI, SourceGDI,
|
|
||||||
&rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
|
|
||||||
|
|
||||||
return(TRUE);
|
do {
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
|
||||||
case DC_COMPLEX:
|
if (RectEnum.c > 0)
|
||||||
|
{
|
||||||
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
|
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
||||||
CD_ANY, ENUM_RECT_LIMIT);
|
RECTL* prcl = &RectEnum.arcl[0];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum),
|
EngIntersectRect(prcl, prcl, DestRect);
|
||||||
(PVOID) &RectEnum);
|
|
||||||
|
|
||||||
if (RectEnum.c > 0)
|
ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
|
||||||
{
|
ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
|
||||||
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
|
|
||||||
RECTL* prcl = &RectEnum.arcl[0];
|
|
||||||
|
|
||||||
do {
|
if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
|
||||||
EngIntersectRect(prcl, prcl, DestRect);
|
prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
|
||||||
|
|
||||||
ptlTmp.x = SourcePoint->x + prcl->left
|
prcl++;
|
||||||
- DestRect->left;
|
|
||||||
ptlTmp.y = SourcePoint->y + prcl->top
|
|
||||||
- DestRect->top;
|
|
||||||
|
|
||||||
CopyBitsCopy(Dest, Source,
|
} while (prcl < prclEnd);
|
||||||
DestGDI, SourceGDI,
|
}
|
||||||
prcl, &ptlTmp, Source->lDelta, ColorTranslation);
|
|
||||||
|
|
||||||
prcl++;
|
} while(EnumMore);
|
||||||
|
|
||||||
} while (prcl < prclEnd);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} while(EnumMore);
|
return FALSE;
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,40 +11,33 @@
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
DWORD STDCALL EngDeviceIoControl(
|
DWORD STDCALL EngDeviceIoControl(
|
||||||
HANDLE hDevice,
|
HANDLE hDevice,
|
||||||
DWORD dwIoControlCode,
|
DWORD dwIoControlCode,
|
||||||
LPVOID lpInBuffer,
|
LPVOID lpInBuffer,
|
||||||
DWORD nInBufferSize,
|
DWORD nInBufferSize,
|
||||||
LPVOID lpOutBuffer,
|
LPVOID lpOutBuffer,
|
||||||
DWORD nOutBufferSize,
|
DWORD nOutBufferSize,
|
||||||
DWORD *lpBytesReturned)
|
DWORD *lpBytesReturned)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
PDRIVER_OBJECT DriverObject;
|
PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
DriverObject = hDevice;
|
DriverObject = hDevice;
|
||||||
|
|
||||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode,
|
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, DriverObject->DeviceObject, lpInBuffer, nInBufferSize,
|
||||||
DriverObject->DeviceObject,
|
lpOutBuffer, nOutBufferSize, FALSE, &Event, &Iosb);
|
||||||
lpInBuffer,
|
|
||||||
nInBufferSize,
|
|
||||||
lpOutBuffer,
|
|
||||||
nOutBufferSize,
|
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&Iosb);
|
|
||||||
|
|
||||||
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
|
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
|
||||||
|
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
|
(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 BuildOrder,
|
||||||
IN ULONG MaxRects)
|
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;
|
ULONG enumCount = 0;
|
||||||
ENUMRECTS enumRects;
|
ENUMRECTS enumRects;
|
||||||
|
|
||||||
// MUCH WORK TO DO HERE
|
// MUCH WORK TO DO HERE
|
||||||
|
|
||||||
// Return the number of rectangles enumerated
|
// Return the number of rectangles enumerated
|
||||||
if(enumCount>MaxRects)
|
if(enumCount>MaxRects)
|
||||||
{
|
{
|
||||||
enumCount = 0xFFFFFFFF;
|
enumCount = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
return enumCount;
|
return enumCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,
|
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
typedef struct _RECT_ENUM
|
typedef struct _RECT_ENUM
|
||||||
{
|
{
|
||||||
ULONG c;
|
ULONG c;
|
||||||
RECTL arcl[ENUM_RECT_LIMIT];
|
RECTL arcl[ENUM_RECT_LIMIT];
|
||||||
} RECT_ENUM;
|
} RECT_ENUM;
|
||||||
|
|
|
@ -18,52 +18,50 @@
|
||||||
|
|
||||||
ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject)
|
ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject)
|
||||||
{
|
{
|
||||||
ULONG NewHandle = HandleCounter++;
|
ULONG NewHandle = HandleCounter++;
|
||||||
|
|
||||||
GDIHandles[NewHandle].InternalObject = InternalObject;
|
GDIHandles[NewHandle].InternalObject = InternalObject;
|
||||||
GDIHandles[NewHandle].UserObject = UserObject;
|
GDIHandles[NewHandle].UserObject = UserObject;
|
||||||
|
|
||||||
return NewHandle;
|
return NewHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FreeGDIHandle(ULONG Handle)
|
VOID FreeGDIHandle(ULONG Handle)
|
||||||
{
|
{
|
||||||
GDIHandles[Handle].InternalObject = NULL;
|
GDIHandles[Handle].InternalObject = NULL;
|
||||||
GDIHandles[Handle].UserObject = NULL;
|
GDIHandles[Handle].UserObject = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID AccessInternalObject(ULONG Handle)
|
PVOID AccessInternalObject(ULONG Handle)
|
||||||
{
|
{
|
||||||
return GDIHandles[Handle].InternalObject;
|
return GDIHandles[Handle].InternalObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID AccessUserObject(ULONG Handle)
|
PVOID AccessUserObject(ULONG Handle)
|
||||||
{
|
{
|
||||||
return GDIHandles[Handle].UserObject;
|
return GDIHandles[Handle].UserObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
|
PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
for(i=0; i<MAX_GDI_HANDLES; i++)
|
for(i=0; i<MAX_GDI_HANDLES; i++)
|
||||||
{
|
{
|
||||||
if(GDIHandles[i].UserObject == UserObject)
|
if(GDIHandles[i].UserObject == UserObject) return GDIHandles[i].InternalObject;
|
||||||
return GDIHandles[i].InternalObject;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG AccessHandleFromUserObject(PVOID UserObject)
|
ULONG AccessHandleFromUserObject(PVOID UserObject)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
for(i=0; i<MAX_GDI_HANDLES; i++)
|
for(i=0; i<MAX_GDI_HANDLES; i++)
|
||||||
{
|
{
|
||||||
if(GDIHandles[i].UserObject == UserObject)
|
if(GDIHandles[i].UserObject == UserObject) return i;
|
||||||
return i;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return INVALID_HANDLE;
|
return INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _GDI_HANDLE {
|
typedef struct _GDI_HANDLE {
|
||||||
ULONG Handle;
|
ULONG Handle;
|
||||||
PVOID InternalObject;
|
PVOID InternalObject;
|
||||||
PVOID UserObject;
|
PVOID UserObject;
|
||||||
} GDI_HANDLE, *PGDI_HANDLE;
|
} GDI_HANDLE, *PGDI_HANDLE;
|
||||||
|
|
||||||
#define INVALID_HANDLE 0
|
#define INVALID_HANDLE 0
|
||||||
|
|
|
@ -1,111 +1,118 @@
|
||||||
#include <ddk/winddi.h>
|
#include <ddk/winddi.h>
|
||||||
#include "objects.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)
|
// 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,
|
BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
|
||||||
LONG x1, LONG y1, LONG x2, LONG y2,
|
LONG x1, LONG y1, LONG x2, LONG y2,
|
||||||
RECTL *RectBounds, MIX mix)
|
RECTL *RectBounds, MIX mix)
|
||||||
{
|
{
|
||||||
SURFGDI *SurfGDI;
|
SURFGDI *SurfGDI;
|
||||||
LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error;
|
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)
|
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
||||||
{
|
|
||||||
// Call the driver's DrvLineTo
|
|
||||||
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2,
|
|
||||||
RectBounds, mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
case 24:
|
||||||
y=y1;
|
DIB_PutPixel = DIB_24BPP_PutPixel;
|
||||||
deltax=x2-x1;
|
DIB_HLine = DIB_24BPP_HLine;
|
||||||
deltay=y2-y1;
|
DIB_VLine = DIB_24BPP_VLine;
|
||||||
|
break;
|
||||||
|
|
||||||
if(deltax<0)
|
default:
|
||||||
{
|
DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
|
||||||
xchange=-1;
|
BitsPerFormat(Surface->iBitmapFormat));
|
||||||
deltax=-deltax;
|
return FALSE;
|
||||||
} else
|
}
|
||||||
{
|
|
||||||
xchange=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deltay<0)
|
// FIXME: Implement clipping
|
||||||
{
|
|
||||||
ychange=-1;
|
x=x1;
|
||||||
deltay=-deltay;
|
y=y1;
|
||||||
} else
|
deltax=x2-x1;
|
||||||
{
|
deltay=y2-y1;
|
||||||
ychange=1;
|
|
||||||
};
|
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;
|
error=0;
|
||||||
i=0;
|
i=0;
|
||||||
|
|
||||||
if(deltax<deltay)
|
if(deltax<deltay)
|
||||||
{
|
{
|
||||||
length=deltay+1;
|
length=deltay+1;
|
||||||
while(i<length)
|
while(i<length)
|
||||||
{
|
{
|
||||||
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
|
DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
|
||||||
y=y+ychange;
|
y=y+ychange;
|
||||||
error=error+deltax;
|
error=error+deltax;
|
||||||
|
|
||||||
if(error>deltay)
|
if(error>deltay)
|
||||||
{
|
{
|
||||||
x=x+xchange;
|
x=x+xchange;
|
||||||
error=error-deltay;
|
error=error-deltay;
|
||||||
}
|
}
|
||||||
i=i+1;
|
i=i+1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
length=deltax+1;
|
length=deltax+1;
|
||||||
while(i<length)
|
while(i<length)
|
||||||
{
|
{
|
||||||
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
|
DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
|
||||||
x=x+xchange;
|
x=x+xchange;
|
||||||
error=error+deltay;
|
error=error+deltay;
|
||||||
if(error>deltax)
|
if(error>deltax)
|
||||||
{
|
{
|
||||||
y=y+ychange;
|
y=y+ychange;
|
||||||
error=error-deltax;
|
error=error-deltax;
|
||||||
}
|
|
||||||
i=i+1;
|
|
||||||
}
|
}
|
||||||
}
|
i=i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,35 +13,34 @@
|
||||||
|
|
||||||
PVOID STDCALL EngAllocMem(ULONG Flags, ULONG MemSize, ULONG Tag)
|
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)
|
if(Flags == FL_ZERO_MEMORY)
|
||||||
{
|
{
|
||||||
RtlZeroMemory(newMem, MemSize);
|
RtlZeroMemory(newMem, MemSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newMem;
|
return newMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL EngFreeMem(PVOID Mem)
|
VOID STDCALL EngFreeMem(PVOID Mem)
|
||||||
{
|
{
|
||||||
ExFreePool(Mem);
|
ExFreePool(Mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag)
|
PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag)
|
||||||
{
|
{
|
||||||
/* PVOID newMem;
|
/* PVOID newMem;
|
||||||
|
|
||||||
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
|
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
|
||||||
MEM_COMMIT, PAGE_READWRITE); */
|
MEM_COMMIT, PAGE_READWRITE); */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL EngFreeUserMem(PVOID pv)
|
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;
|
} BRUSHGDI;
|
||||||
|
|
||||||
typedef struct _CLIPGDI {
|
typedef struct _CLIPGDI {
|
||||||
ULONG NumRegionRects;
|
ULONG NumRegionRects;
|
||||||
ULONG NumIntersectRects;
|
ULONG NumIntersectRects;
|
||||||
RECTL *RegionRects;
|
RECTL *RegionRects;
|
||||||
RECTL *IntersectRects;
|
RECTL *IntersectRects;
|
||||||
|
|
||||||
ULONG EnumPos;
|
ULONG EnumPos;
|
||||||
ENUMRECTS EnumRects;
|
ENUMRECTS EnumRects;
|
||||||
} CLIPGDI, *PCLIPGDI;
|
} CLIPGDI, *PCLIPGDI;
|
||||||
|
|
||||||
typedef struct _DRVFUNCTIONSGDI {
|
typedef struct _DRVFUNCTIONSGDI {
|
||||||
HDEV hdev;
|
HDEV hdev;
|
||||||
DRVFN Functions[INDEX_LAST];
|
DRVFN Functions[INDEX_LAST];
|
||||||
} DRVFUNCTIONSGDI;
|
} DRVFUNCTIONSGDI;
|
||||||
|
|
||||||
typedef struct _FLOATGDI {
|
typedef struct _FLOATGDI {
|
||||||
|
@ -36,12 +36,12 @@ typedef struct _FONTGDI {
|
||||||
} FONTGDI;
|
} FONTGDI;
|
||||||
|
|
||||||
typedef struct _PALGDI {
|
typedef struct _PALGDI {
|
||||||
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
|
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
|
||||||
ULONG NumColors;
|
ULONG NumColors;
|
||||||
ULONG *IndexedColors;
|
ULONG *IndexedColors;
|
||||||
ULONG RedMask;
|
ULONG RedMask;
|
||||||
ULONG GreenMask;
|
ULONG GreenMask;
|
||||||
ULONG BlueMask;
|
ULONG BlueMask;
|
||||||
} PALGDI, *PPALGDI;
|
} PALGDI, *PPALGDI;
|
||||||
|
|
||||||
typedef struct _PATHGDI {
|
typedef struct _PATHGDI {
|
||||||
|
@ -88,21 +88,24 @@ typedef VOID (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL);
|
||||||
|
|
||||||
typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
|
typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
|
||||||
|
|
||||||
typedef struct _SURFGDI {
|
typedef BOOL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG);
|
||||||
BYTE BytesPerPixel;
|
|
||||||
|
|
||||||
PFN_BitBlt BitBlt;
|
typedef struct _SURFGDI {
|
||||||
PFN_StretchBlt StretchBlt;
|
INT BitsPerPixel;
|
||||||
PFN_TextOut TextOut;
|
|
||||||
PFN_Paint Paint;
|
PFN_BitBlt BitBlt;
|
||||||
PFN_StrokePath StrokePath;
|
PFN_StretchBlt StretchBlt;
|
||||||
PFN_FillPath FillPath;
|
PFN_TextOut TextOut;
|
||||||
PFN_StrokeAndFillPath StrokeAndFillPath;
|
PFN_Paint Paint;
|
||||||
PFN_LineTo LineTo;
|
PFN_StrokePath StrokePath;
|
||||||
PFN_CopyBits CopyBits;
|
PFN_FillPath FillPath;
|
||||||
PFN_Synchronize Synchronize;
|
PFN_StrokeAndFillPath StrokeAndFillPath;
|
||||||
BOOL SynchronizeAccess;
|
PFN_LineTo LineTo;
|
||||||
PFN_CreateDeviceBitmap CreateDeviceBitmap;
|
PFN_CopyBits CopyBits;
|
||||||
|
PFN_Synchronize Synchronize;
|
||||||
|
BOOL SynchronizeAccess;
|
||||||
|
PFN_CreateDeviceBitmap CreateDeviceBitmap;
|
||||||
|
PFN_SetPalette SetPalette;
|
||||||
} SURFGDI, *PSURFGDI;
|
} SURFGDI, *PSURFGDI;
|
||||||
|
|
||||||
typedef struct _XFORMGDI {
|
typedef struct _XFORMGDI {
|
||||||
|
@ -110,10 +113,10 @@ typedef struct _XFORMGDI {
|
||||||
} XFORMGDI;
|
} XFORMGDI;
|
||||||
|
|
||||||
typedef struct _XLATEGDI {
|
typedef struct _XLATEGDI {
|
||||||
HPALETTE DestPal;
|
HPALETTE DestPal;
|
||||||
HPALETTE SourcePal;
|
HPALETTE SourcePal;
|
||||||
|
|
||||||
ULONG *translationTable;
|
ULONG *translationTable;
|
||||||
} XLATEGDI;
|
} XLATEGDI;
|
||||||
|
|
||||||
// List of GDI objects
|
// List of GDI objects
|
||||||
|
|
|
@ -15,80 +15,75 @@
|
||||||
|
|
||||||
BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
|
BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
|
||||||
{
|
{
|
||||||
ULONG x, y, LineWidth, leftOfBitmap;
|
ULONG x, y, LineWidth, leftOfBitmap;
|
||||||
SURFGDI *SurfaceGDI;
|
SURFGDI *SurfaceGDI;
|
||||||
|
|
||||||
SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
|
SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
|
||||||
LineWidth = Dimensions->right - Dimensions->left;
|
LineWidth = Dimensions->right - Dimensions->left;
|
||||||
|
|
||||||
for (y = Dimensions->top; y < Dimensions->bottom; y++)
|
for (y = Dimensions->top; y < Dimensions->bottom; y++)
|
||||||
{
|
{
|
||||||
EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
|
// EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
|
BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
|
||||||
BRUSHINST *BrushInst, POINTL *BrushPoint)
|
BRUSHINST *BrushInst, POINTL *BrushPoint)
|
||||||
{
|
{
|
||||||
RECT_ENUM RectEnum;
|
RECT_ENUM RectEnum;
|
||||||
BOOL EnumMore;
|
BOOL EnumMore;
|
||||||
|
|
||||||
switch(ClipRegion->iMode) {
|
switch(ClipRegion->iMode) {
|
||||||
|
|
||||||
case TC_RECTANGLES:
|
case TC_RECTANGLES:
|
||||||
|
|
||||||
/* Rectangular clipping can be handled without enumeration.
|
/* Rectangular clipping can be handled without enumeration.
|
||||||
Note that trivial clipping is not possible, since the clipping
|
Note that trivial clipping is not possible, since the clipping
|
||||||
region defines the area to fill */
|
region defines the area to fill */
|
||||||
|
|
||||||
if (ClipRegion->iDComplexity == DC_RECT)
|
if (ClipRegion->iDComplexity == DC_RECT)
|
||||||
{
|
{
|
||||||
FillSolid(Surface, &ClipRegion->rclBounds, iColor);
|
FillSolid(Surface, &ClipRegion->rclBounds, iColor);
|
||||||
} else {
|
} 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,
|
do {
|
||||||
ENUM_RECT_LIMIT);
|
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
FillSolid(Surface, &RectEnum.arcl[0], iColor);
|
||||||
|
} while (EnumMore);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
return(TRUE);
|
||||||
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
|
|
||||||
|
|
||||||
FillSolid(Surface, &RectEnum.arcl[0], iColor);
|
default:
|
||||||
|
return(FALSE);
|
||||||
} while (EnumMore);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
|
BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
|
||||||
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
|
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
|
||||||
IN MIX Mix)
|
IN MIX Mix)
|
||||||
{
|
{
|
||||||
SURFGDI *SurfGDI;
|
SURFGDI *SurfGDI;
|
||||||
|
|
||||||
// Is the surface's Paint function hooked?
|
// Is the surface's Paint function hooked?
|
||||||
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
SurfGDI = AccessInternalObjectFromUserObject(Surface);
|
||||||
|
|
||||||
if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
|
if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
|
||||||
{
|
{
|
||||||
// Call the driver's DrvPaint
|
// Call the driver's DrvPaint
|
||||||
return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
|
return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: We only support a brush's solid color attribute
|
// FIXME: We only support a brush's solid color attribute
|
||||||
return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL,
|
return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin));
|
||||||
BrushOrigin));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL EngEraseSurface(SURFOBJ *Surface, RECTL *Rect, ULONG iColor)
|
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 Green,
|
||||||
ULONG Blue)
|
ULONG Blue)
|
||||||
{
|
{
|
||||||
HPALETTE NewPalette;
|
HPALETTE NewPalette;
|
||||||
PALOBJ *PalObj;
|
PALOBJ *PalObj;
|
||||||
PALGDI *PalGDI;
|
PALGDI *PalGDI;
|
||||||
|
|
||||||
PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
|
PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
|
||||||
PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), 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)
|
if(Colors != NULL)
|
||||||
{
|
{
|
||||||
PalGDI->NumColors = NumColors;
|
PalGDI->IndexedColors = ExAllocatePool(NonPagedPool, sizeof(ULONG)*NumColors);
|
||||||
PalGDI->IndexedColors = Colors;
|
RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(ULONG)*NumColors);
|
||||||
} else
|
}
|
||||||
if(Mode==PAL_BITFIELDS)
|
|
||||||
{
|
|
||||||
PalGDI->RedMask = Red;
|
|
||||||
PalGDI->GreenMask = Green;
|
|
||||||
PalGDI->BlueMask = Blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
BOOL EngDeletePalette(IN HPALETTE Palette)
|
||||||
{
|
{
|
||||||
PALOBJ *PalObj;
|
PALOBJ *PalObj;
|
||||||
PALGDI *PalGDI;
|
PALGDI *PalGDI;
|
||||||
|
|
||||||
PalGDI = AccessInternalObject(Palette);
|
PalGDI = AccessInternalObject(Palette);
|
||||||
PalObj = AccessInternalObject(Palette);
|
PalObj = AccessInternalObject(Palette);
|
||||||
|
|
||||||
EngFreeMem(PalGDI);
|
EngFreeMem(PalGDI);
|
||||||
EngFreeMem(PalObj);
|
EngFreeMem(PalObj);
|
||||||
FreeGDIHandle(Palette);
|
FreeGDIHandle(Palette);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors,
|
ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors,
|
||||||
ULONG *PaletteEntry)
|
ULONG *PaletteEntry)
|
||||||
{
|
{
|
||||||
ULONG i, entry;
|
ULONG i, entry;
|
||||||
PALGDI *PalGDI;
|
PALGDI *PalGDI;
|
||||||
|
|
||||||
PalGDI = AccessInternalObjectFromUserObject(PalObj);
|
PalGDI = AccessInternalObjectFromUserObject(PalObj);
|
||||||
|
|
||||||
for(i=Start; i<Colors; i++)
|
for(i=Start; i<Colors; i++)
|
||||||
{
|
{
|
||||||
PaletteEntry[i] = PalGDI->IndexedColors[i];
|
PaletteEntry[i] = PalGDI->IndexedColors[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Colors;
|
return Colors;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,64 +6,72 @@
|
||||||
* PROGRAMER: Jason Filby
|
* PROGRAMER: Jason Filby
|
||||||
* REVISION HISTORY:
|
* REVISION HISTORY:
|
||||||
* 3/7/1999: Created
|
* 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 <ddk/winddi.h>
|
||||||
#include <win32k/dc.h>
|
#include <win32k/dc.h>
|
||||||
#include "objects.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
|
switch(Format)
|
||||||
// pixel size if < 1 byte we expand it to 1 byte
|
{
|
||||||
|
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)
|
ULONG BitmapFormat(WORD Bits, DWORD Compression)
|
||||||
{
|
{
|
||||||
return 1;
|
switch(Compression)
|
||||||
} else
|
{
|
||||||
if((Format==BMF_4BPP) || (Format==BMF_4RLE))
|
case BI_RGB:
|
||||||
{
|
switch(Bits)
|
||||||
return 1;
|
{
|
||||||
} else
|
case 1: return BMF_1BPP;
|
||||||
if((Format==BMF_8BPP) || (Format==BMF_8RLE))
|
case 4: return BMF_4BPP;
|
||||||
{
|
case 8: return BMF_8BPP;
|
||||||
return 1;
|
case 16: return BMF_16BPP;
|
||||||
} else
|
case 24: return BMF_24BPP;
|
||||||
if(Format==BMF_16BPP)
|
case 32: return BMF_32BPP;
|
||||||
{
|
}
|
||||||
return 2;
|
|
||||||
} else
|
|
||||||
if(Format==BMF_24BPP)
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
} else
|
|
||||||
if(Format==BMF_32BPP)
|
|
||||||
{
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
case BI_RLE4: return BMF_4RLE;
|
||||||
|
case BI_RLE8: return BMF_8RLE;
|
||||||
|
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID InitializeHooks(SURFGDI *SurfGDI)
|
VOID InitializeHooks(SURFGDI *SurfGDI)
|
||||||
{
|
{
|
||||||
SurfGDI->BitBlt = NULL;
|
SurfGDI->BitBlt = NULL;
|
||||||
SurfGDI->CopyBits = NULL;
|
SurfGDI->CopyBits = NULL;
|
||||||
SurfGDI->CreateDeviceBitmap = NULL;
|
SurfGDI->CreateDeviceBitmap = NULL;
|
||||||
|
SurfGDI->SetPalette = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
||||||
{
|
{
|
||||||
HBITMAP NewBitmap;
|
HBITMAP NewBitmap;
|
||||||
SURFOBJ *SurfObj;
|
SURFOBJ *SurfObj;
|
||||||
|
|
||||||
NewBitmap = EngCreateBitmap(Size, bytesPerPixel(Format) * Size.cx, Format, 0, NULL);
|
NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
|
||||||
SurfObj = AccessUserObject(NewBitmap);
|
SurfObj = (PVOID)AccessUserObject(NewBitmap);
|
||||||
SurfObj->dhpdev = dhsurf;
|
SurfObj->dhpdev = dhsurf;
|
||||||
|
|
||||||
return NewBitmap;
|
return NewBitmap;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP EngCreateBitmap(IN SIZEL Size,
|
HBITMAP EngCreateBitmap(IN SIZEL Size,
|
||||||
|
@ -72,141 +80,134 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
|
||||||
IN ULONG Flags,
|
IN ULONG Flags,
|
||||||
IN PVOID Bits)
|
IN PVOID Bits)
|
||||||
{
|
{
|
||||||
HBITMAP NewBitmap;
|
HBITMAP NewBitmap;
|
||||||
SURFOBJ *SurfObj;
|
SURFOBJ *SurfObj;
|
||||||
SURFGDI *SurfGDI;
|
SURFGDI *SurfGDI;
|
||||||
|
|
||||||
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
|
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), 0);
|
||||||
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
|
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), 0);
|
||||||
|
|
||||||
NewBitmap = CreateGDIHandle(SurfGDI, SurfObj);
|
NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
|
||||||
|
|
||||||
InitializeHooks(SurfGDI);
|
InitializeHooks(SurfGDI);
|
||||||
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
|
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
|
||||||
|
SurfObj->lDelta = Width;
|
||||||
|
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
||||||
|
|
||||||
SurfObj->lDelta = ((bytesPerPixel(Format) * Width) + 31) & ~31; // round up 4 bytes
|
if(Bits!=NULL)
|
||||||
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
{
|
||||||
|
SurfObj->pvBits = Bits;
|
||||||
if(Bits!=NULL)
|
} else
|
||||||
{
|
{
|
||||||
SurfObj->pvBits = Bits;
|
if(Flags & BMF_USERMEM)
|
||||||
} else
|
{
|
||||||
{
|
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
|
||||||
if(Flags & BMF_USERMEM)
|
} else {
|
||||||
|
if(Flags & BMF_NOZEROINIT)
|
||||||
{
|
{
|
||||||
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
|
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
|
||||||
} else {
|
} else {
|
||||||
if(Flags & BMF_NOZEROINIT)
|
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
|
||||||
{
|
|
||||||
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
|
|
||||||
} else {
|
|
||||||
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SurfObj->dhsurf = 0; // device managed surface
|
SurfObj->dhsurf = 0; // device managed surface
|
||||||
SurfObj->hsurf = 0;
|
SurfObj->hsurf = 0;
|
||||||
SurfObj->sizlBitmap = Size;
|
SurfObj->sizlBitmap = Size;
|
||||||
SurfObj->iBitmapFormat = Format;
|
SurfObj->iBitmapFormat = Format;
|
||||||
SurfObj->iType = STYPE_BITMAP;
|
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 EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
||||||
{
|
{
|
||||||
HSURF NewSurface;
|
HSURF NewSurface;
|
||||||
SURFOBJ *SurfObj;
|
SURFOBJ *SurfObj;
|
||||||
SURFGDI *SurfGDI;
|
SURFGDI *SurfGDI;
|
||||||
|
|
||||||
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
|
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
|
||||||
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), 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;
|
return NewSurface;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
|
PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
for(i=0; i<DED->c; i++)
|
for(i=0; i<DED->c; i++)
|
||||||
{
|
{
|
||||||
if(DED->pdrvfn[i].iFunc == DriverFunc)
|
if(DED->pdrvfn[i].iFunc == DriverFunc)
|
||||||
return DED->pdrvfn[i].pfn;
|
return DED->pdrvfn[i].pfn;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
|
BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
|
||||||
{
|
{
|
||||||
SURFOBJ *SurfObj;
|
SURFOBJ *SurfObj;
|
||||||
SURFGDI *SurfGDI;
|
SURFGDI *SurfGDI;
|
||||||
|
|
||||||
// it looks like this Dev is actually a pointer to the DC!
|
PDC Dc = (PDC)Dev;
|
||||||
PDC Dc = (PDC)Dev;
|
|
||||||
DbgPrint("Associate 1\n");
|
|
||||||
// DRVENABLEDATA *DED;
|
|
||||||
|
|
||||||
SurfGDI = AccessInternalObject(Surface);
|
SurfGDI = (PVOID)AccessInternalObject(Surface);
|
||||||
SurfObj = AccessUserObject(Surface);
|
SurfObj = (PVOID)AccessUserObject(Surface);
|
||||||
|
|
||||||
// DED = AccessInternalObject(Dev);
|
// Associate the hdev
|
||||||
|
SurfObj->hdev = Dev;
|
||||||
|
|
||||||
// Associate the hdev
|
// Hook up specified functions
|
||||||
SurfObj->hdev = Dev;
|
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
|
SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
|
||||||
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
|
SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
|
||||||
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;
|
return TRUE;
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL EngDeleteSurface(HSURF Surface)
|
BOOL EngDeleteSurface(HSURF Surface)
|
||||||
{
|
{
|
||||||
SURFOBJ *SurfObj;
|
SURFOBJ *SurfObj;
|
||||||
SURFGDI *SurfGDI;
|
SURFGDI *SurfGDI;
|
||||||
|
|
||||||
SurfGDI = AccessInternalObject(Surface);
|
SurfGDI = AccessInternalObject(Surface);
|
||||||
SurfObj = AccessUserObject(Surface);
|
SurfObj = AccessUserObject(Surface);
|
||||||
|
|
||||||
EngFreeMem(SurfGDI);
|
EngFreeMem(SurfGDI);
|
||||||
EngFreeMem(SurfObj);
|
EngFreeMem(SurfObj);
|
||||||
FreeGDIHandle(Surface);
|
FreeGDIHandle(Surface);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SURFOBJ *EngLockSurface(HSURF Surface)
|
SURFOBJ *EngLockSurface(HSURF Surface)
|
||||||
{
|
{
|
||||||
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
|
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
|
||||||
|
return AccessUserObject(Surface);
|
||||||
return AccessUserObject(Surface);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,251 +18,249 @@ ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
|
||||||
|
|
||||||
ULONG RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue)
|
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)
|
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)
|
INT abs(INT nm)
|
||||||
{
|
{
|
||||||
if(nm<0)
|
if(nm<0)
|
||||||
{
|
{
|
||||||
return nm * -1;
|
return nm * -1;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return nm;
|
return nm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: If the caller knows that the destinations are indexed and not RGB
|
// 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.
|
// then we should cache more than one value. Same with the source.
|
||||||
|
|
||||||
|
// Takes indexed palette and a
|
||||||
ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
||||||
ULONG NumColors)
|
ULONG NumColors)
|
||||||
{
|
{
|
||||||
PVIDEO_CLUTDATA cSourceColor;
|
PVIDEO_CLUTDATA cSourceColor;
|
||||||
PVIDEO_CLUTDATA cDestColors;
|
PVIDEO_CLUTDATA cDestColors;
|
||||||
ULONG bestMatch = 256, idx = 0, i;
|
ULONG bestMatch = 256, idx = 0, i;
|
||||||
ULONG rt;
|
ULONG rt;
|
||||||
|
|
||||||
// Simple cache -- only one value because we don't want to waste time
|
// Simple cache -- only one value because we don't want to waste time
|
||||||
// if the colors aren't very sequential
|
// if the colors aren't very sequential
|
||||||
|
|
||||||
if(SourceColor == CCMLastSourceColor)
|
if(SourceColor == CCMLastSourceColor)
|
||||||
{
|
{
|
||||||
return CCMLastColorMatch;
|
return CCMLastColorMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSourceColor = &SourceColor;
|
cSourceColor = &SourceColor;
|
||||||
|
|
||||||
for (i=0; i<NumColors; i++)
|
for (i=0; i<NumColors; i++)
|
||||||
{
|
{
|
||||||
cDestColors = &DestColors[i];
|
cDestColors = &DestColors[i];
|
||||||
|
|
||||||
rt = ( abs(cSourceColor->Red - cDestColors->Red) +
|
rt = ( abs(cSourceColor->Red - cDestColors->Red) +
|
||||||
abs(cSourceColor->Green - cDestColors->Green) +
|
abs(cSourceColor->Green - cDestColors->Green) +
|
||||||
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
|
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
|
||||||
|
|
||||||
if(rt<=bestMatch)
|
if(rt<=bestMatch)
|
||||||
{
|
{
|
||||||
idx = i;
|
idx = i;
|
||||||
bestMatch = rt;
|
bestMatch = rt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMLastSourceColor = SourceColor;
|
CCMLastSourceColor = SourceColor;
|
||||||
CCMLastColorMatch = idx;
|
CCMLastColorMatch = idx;
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
|
VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
|
||||||
PALGDI *PalDest, PALGDI *PalSource)
|
PALGDI *PalDest, PALGDI *PalSource)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
for(i=0; i<PalSource->NumColors; i++)
|
for(i=0; i<PalSource->NumColors; i++)
|
||||||
{
|
{
|
||||||
TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i],
|
TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors);
|
||||||
PalDest->IndexedColors, PalDest->NumColors);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
|
XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
|
||||||
HPALETTE PaletteDest, HPALETTE PaletteSource)
|
HPALETTE PaletteDest, HPALETTE PaletteSource)
|
||||||
{
|
{
|
||||||
// FIXME: Add support for BGR conversions
|
// FIXME: Add support for BGR conversions
|
||||||
|
|
||||||
HPALETTE NewXlate;
|
HPALETTE NewXlate;
|
||||||
XLATEOBJ *XlateObj;
|
XLATEOBJ *XlateObj;
|
||||||
XLATEGDI *XlateGDI;
|
XLATEGDI *XlateGDI;
|
||||||
PALGDI *SourcePalGDI, *DestPalGDI;
|
PALGDI *SourcePalGDI, *DestPalGDI;
|
||||||
ULONG IndexedColors;
|
ULONG IndexedColors;
|
||||||
|
|
||||||
XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
|
XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
|
||||||
XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
|
XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
|
||||||
|
|
||||||
NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
|
NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
|
||||||
|
|
||||||
if(SourcePalType == PAL_INDEXED)
|
if(SourcePalType == PAL_INDEXED)
|
||||||
{
|
{
|
||||||
SourcePalGDI = AccessInternalObject(PaletteSource);
|
SourcePalGDI = AccessInternalObject(PaletteSource);
|
||||||
} else
|
} else
|
||||||
if(DestPalType == PAL_INDEXED)
|
if(DestPalType == PAL_INDEXED)
|
||||||
{
|
{
|
||||||
DestPalGDI = AccessInternalObject(PaletteDest);
|
DestPalGDI = AccessInternalObject(PaletteDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
XlateObj->iSrcType = SourcePalType;
|
XlateObj->iSrcType = SourcePalType;
|
||||||
XlateObj->iDstType = DestPalType;
|
XlateObj->iDstType = DestPalType;
|
||||||
|
|
||||||
// Store handles of palettes in internal Xlate GDI object (or NULLs)
|
// Store handles of palettes in internal Xlate GDI object (or NULLs)
|
||||||
XlateGDI->DestPal = PaletteDest;
|
XlateGDI->DestPal = PaletteDest;
|
||||||
XlateGDI->SourcePal = PaletteSource;
|
XlateGDI->SourcePal = PaletteSource;
|
||||||
|
|
||||||
XlateObj->flXlate = 0;
|
XlateObj->flXlate = 0;
|
||||||
|
|
||||||
// If source and destination palettes are the same or if they're RGB/BGR
|
// If source and destination palettes are the same or if they're RGB/BGR
|
||||||
if( (PaletteDest == PaletteSource) ||
|
if( (PaletteDest == PaletteSource) ||
|
||||||
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
|
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
|
||||||
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
|
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
|
||||||
{
|
{
|
||||||
XlateObj->flXlate |= XO_TRIVIAL;
|
XlateObj->flXlate |= XO_TRIVIAL;
|
||||||
}
|
return XlateObj;
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare the translation table
|
// Prepare the translation table
|
||||||
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
||||||
{
|
{
|
||||||
XlateObj->flXlate |= XO_TABLE;
|
XlateObj->flXlate |= XO_TABLE;
|
||||||
|
|
||||||
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
|
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
|
||||||
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
|
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
|
||||||
|
|
||||||
XlateGDI->translationTable = EngAllocMem(
|
XlateGDI->translationTable = EngAllocMem(FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
|
||||||
FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Source palette is indexed
|
// Source palette is indexed
|
||||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||||
{
|
{
|
||||||
if(XlateObj->iDstType == PAL_INDEXED)
|
if(XlateObj->iDstType == PAL_INDEXED)
|
||||||
{
|
{
|
||||||
// Converting from indexed to indexed
|
// Converting from indexed to indexed
|
||||||
IndexedToIndexedTranslationTable(XlateGDI->translationTable,
|
IndexedToIndexedTranslationTable(XlateGDI->translationTable, DestPalGDI, SourcePalGDI);
|
||||||
DestPalGDI, SourcePalGDI);
|
} else
|
||||||
} else
|
|
||||||
if(XlateObj->iDstType == PAL_RGB)
|
if(XlateObj->iDstType == PAL_RGB)
|
||||||
{
|
{
|
||||||
// FIXME: Is this necessary? I think the driver has to call this
|
// FIXME: Is this necessary? I think the driver has to call this
|
||||||
// function anyways if pulXlate is NULL and Source is PAL_INDEXED
|
// 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,
|
XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
|
||||||
SourcePalGDI->NumColors,
|
SourcePalGDI->NumColors,
|
||||||
XlateGDI->translationTable);
|
XlateGDI->translationTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
XlateObj->pulXlate = XlateGDI->translationTable;
|
XlateObj->pulXlate = XlateGDI->translationTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source palette is RGB
|
// Source palette is RGB
|
||||||
if(XlateObj->iSrcType == PAL_RGB)
|
if(XlateObj->iSrcType == PAL_RGB)
|
||||||
{
|
{
|
||||||
if(XlateObj->iDstType == PAL_INDEXED)
|
if(XlateObj->iDstType == PAL_INDEXED)
|
||||||
{
|
{
|
||||||
// FIXME: Is this necessary? I think the driver has to call this
|
// FIXME: Is this necessary? I think the driver has to call this
|
||||||
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED
|
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED
|
||||||
|
|
||||||
// Converting from RGB to indexed
|
// Converting from RGB to indexed
|
||||||
XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE,
|
XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE, DestPalGDI->NumColors, XlateGDI->translationTable);
|
||||||
DestPalGDI->NumColors,
|
}
|
||||||
XlateGDI->translationTable);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Add support for XO_TO_MONO
|
// FIXME: Add support for XO_TO_MONO
|
||||||
|
return XlateObj;
|
||||||
return XlateObj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EngDeleteXlate(XLATEOBJ *XlateObj)
|
EngDeleteXlate(XLATEOBJ *XlateObj)
|
||||||
{
|
{
|
||||||
HPALETTE HXlate = AccessHandleFromUserObject(XlateObj);
|
HPALETTE HXlate = AccessHandleFromUserObject(XlateObj);
|
||||||
XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
|
XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
|
||||||
|
|
||||||
if(XlateGDI->translationTable!=NULL)
|
if(XlateGDI->translationTable!=NULL)
|
||||||
{
|
{
|
||||||
EngFreeMem(XlateGDI->translationTable);
|
EngFreeMem(XlateGDI->translationTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
EngFreeMem(XlateGDI);
|
EngFreeMem(XlateGDI);
|
||||||
EngFreeMem(XlateObj);
|
EngFreeMem(XlateObj);
|
||||||
FreeGDIHandle(HXlate);
|
FreeGDIHandle(HXlate);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG *XLATEOBJ_piVector(XLATEOBJ *XlateObj)
|
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 NULL;
|
||||||
{
|
|
||||||
return XlateGDI->translationTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
|
ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
|
||||||
{
|
{
|
||||||
PALGDI *PalGDI;
|
PALGDI *PalGDI;
|
||||||
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||||
|
|
||||||
if(XlateObj->iSrcType == PAL_RGB)
|
if(XlateObj->flXlate & XO_TRIVIAL)
|
||||||
{
|
{
|
||||||
// FIXME: should we cache colors used often?
|
return Color;
|
||||||
// FIXME: won't work if destination isn't indexed
|
} 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
|
// Extract the destination palette
|
||||||
PalGDI = AccessInternalObject(XlateGDI->DestPal);
|
PalGDI = AccessInternalObject(XlateGDI->DestPal);
|
||||||
|
|
||||||
// Return closest match for the given RGB color
|
// Return closest match for the given RGB color
|
||||||
return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
|
return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
|
||||||
} else
|
} else
|
||||||
|
if(XlateObj->iSrcType == PAL_INDEXED)
|
||||||
|
{
|
||||||
|
return XlateGDI->translationTable[Color];
|
||||||
|
}
|
||||||
|
|
||||||
if(XlateObj->iSrcType == PAL_INDEXED)
|
return 0;
|
||||||
{
|
|
||||||
return XlateGDI->translationTable[Color];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
|
ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
|
||||||
ULONG PalOutType, ULONG cPal, ULONG *OutPal)
|
ULONG PalOutType, ULONG cPal, ULONG *OutPal)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
HPALETTE HPal;
|
HPALETTE HPal;
|
||||||
XLATEGDI *XlateGDI;
|
XLATEGDI *XlateGDI;
|
||||||
PALGDI *PalGDI;
|
PALGDI *PalGDI;
|
||||||
|
|
||||||
XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
|
||||||
|
|
||||||
if(PalOutType == XO_SRCPALETTE)
|
if(PalOutType == XO_SRCPALETTE)
|
||||||
{
|
{
|
||||||
HPal = XlateGDI->SourcePal;
|
HPal = XlateGDI->SourcePal;
|
||||||
} else
|
} else
|
||||||
if(PalOutType == XO_DESTPALETTE)
|
if(PalOutType == XO_DESTPALETTE)
|
||||||
{
|
{
|
||||||
HPal = XlateGDI->DestPal;
|
HPal = XlateGDI->DestPal;
|
||||||
}
|
}
|
||||||
|
|
||||||
PalGDI = AccessInternalObject(HPal);
|
PalGDI = AccessInternalObject(HPal);
|
||||||
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
|
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,9 +285,11 @@ void CreateCellCharSurface()
|
||||||
surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI));
|
surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI));
|
||||||
|
|
||||||
hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel
|
hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel
|
||||||
|
|
||||||
pbo = BITMAPOBJ_HandleToPtr(hCharCellBitmap);
|
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,
|
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/ntddk.h>
|
||||||
#include <ddk/winddi.h>
|
#include <ddk/winddi.h>
|
||||||
|
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
STDCALL
|
STDCALL
|
||||||
EngLoadImage (LPWSTR DriverName)
|
EngLoadImage (LPWSTR DriverName)
|
||||||
{
|
{
|
||||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
|
||||||
DriverName);
|
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
if (!NT_SUCCESS(Status)) return NULL;
|
||||||
&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
|
STDCALL
|
||||||
EngLoadModule(LPWSTR ModuleName)
|
EngLoadModule(LPWSTR ModuleName)
|
||||||
{
|
{
|
||||||
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
// FIXME: should load as readonly
|
// FIXME: should load as readonly
|
||||||
|
|
||||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
RtlInitUnicodeString (&GdiDriverInfo.DriverName, ModuleName);
|
||||||
ModuleName);
|
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
if (!NT_SUCCESS(Status)) return NULL;
|
||||||
&GdiDriverInfo,
|
|
||||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return (HANDLE)GdiDriverInfo.ImageAddress;
|
return (HANDLE)GdiDriverInfo.ImageAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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
|
* Entry Point for win32k.sys
|
||||||
*/
|
*/
|
||||||
|
@ -25,31 +25,26 @@
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
DllMain (
|
DllMain (
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PUNICODE_STRING RegistryPath
|
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
|
* Register user mode call interface
|
||||||
* (system service table index = 1)
|
* (system service table index = 1)
|
||||||
*/
|
*/
|
||||||
Result = KeAddSystemServiceTable (Win32kSSDT,
|
Result = KeAddSystemServiceTable (Win32kSSDT, NULL, NUMBER_OF_SYSCALLS, Win32kSSPT, 1);
|
||||||
NULL,
|
if (Result == FALSE)
|
||||||
NUMBER_OF_SYSCALLS,
|
{
|
||||||
Win32kSSPT,
|
DbgPrint("Adding system services failed!\n");
|
||||||
1);
|
return STATUS_UNSUCCESSFUL;
|
||||||
if (Result == FALSE)
|
}
|
||||||
{
|
|
||||||
DbgPrint("Adding system services failed!\n");
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgPrint("System services added successfully!\n");
|
DbgPrint("System services added successfully!\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,14 +52,19 @@ BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kInitialize (VOID)
|
W32kInitialize (VOID)
|
||||||
{
|
{
|
||||||
|
// FIXME: Retrieve name from registry
|
||||||
|
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
||||||
|
|
||||||
// FIXME: Retrieve name from registry
|
// Create surface used to draw the internal font onto
|
||||||
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
CreateCellCharSurface();
|
||||||
|
|
||||||
// Create surface used to draw the internal font onto
|
// Create stock objects, ie. precreated objects commonly used by win32 applications
|
||||||
CreateCellCharSurface();
|
CreateStockObjects();
|
||||||
|
|
||||||
return TRUE;
|
// Initialize FreeType library
|
||||||
|
if(!InitFontSupport()) return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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
|
# WIN32K.SYS build spec
|
||||||
#
|
#
|
||||||
|
@ -6,8 +6,13 @@ PATH_TO_TOP = ../..
|
||||||
|
|
||||||
TARGET=win32k
|
TARGET=win32k
|
||||||
|
|
||||||
|
# from atheos appserver makefile
|
||||||
|
COPTS = -pipe -O3 -I./freetype2-beta8/include -c -Wall
|
||||||
|
|
||||||
CFLAGS = -I.
|
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_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/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
|
||||||
eng/surface.o eng/xlate.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/line.o objects/metafile.o objects/paint.o \
|
||||||
objects/path.o objects/pen.o objects/print.o \
|
objects/path.o objects/pen.o objects/print.o \
|
||||||
objects/region.o objects/text.o objects/wingl.o \
|
objects/region.o objects/text.o objects/wingl.o \
|
||||||
objects/bezier.o objects/objconv.o
|
objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
|
||||||
FREETYPE_OBJECTS = freetype/grfont.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
|
RESOURCE_OBJECT = $(TARGET).coff
|
||||||
STUBS_OBJECTS = stubs/stubs.o
|
STUBS_OBJECTS = stubs/stubs.o
|
||||||
|
|
||||||
OBJECTS = $(ENG_OBJECTS) $(MAIN_OBJECTS) $(MISC_OBJECTS) $(LDR_OBJECTS) $(OBJECTS_OBJECTS) \
|
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
|
all: $(TARGET).sys
|
||||||
|
|
||||||
|
@ -116,4 +126,3 @@ $(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||||
#WIN32_LEAN_AND_MEAN = yes
|
#WIN32_LEAN_AND_MEAN = yes
|
||||||
#WARNINGS_ARE_ERRORS = yes
|
#WARNINGS_ARE_ERRORS = yes
|
||||||
include ../../rules.mak
|
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
|
* GDI Driver support routines
|
||||||
* (mostly swiped from Wine)
|
* (mostly swiped from Wine)
|
||||||
|
@ -34,28 +34,23 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
|
||||||
{
|
{
|
||||||
PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver));
|
PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver));
|
||||||
DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
|
DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
|
||||||
if (!Driver)
|
if (!Driver) return FALSE;
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
Driver->ReferenceCount = 0;
|
Driver->ReferenceCount = 0;
|
||||||
Driver->EnableDriver = EnableDriver;
|
Driver->EnableDriver = EnableDriver;
|
||||||
if (Name)
|
if (Name)
|
||||||
{
|
{
|
||||||
Driver->Name = ExAllocatePool(PagedPool,
|
Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR));
|
||||||
(wcslen(Name) + 1) * sizeof(WCHAR));
|
wcscpy(Driver->Name, Name);
|
||||||
wcscpy(Driver->Name, Name);
|
Driver->Next = DriverList;
|
||||||
Driver->Next = DriverList;
|
DriverList = Driver;
|
||||||
DriverList = Driver;
|
return TRUE;
|
||||||
return TRUE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (GenericDriver != NULL)
|
if (GenericDriver != NULL)
|
||||||
{
|
{
|
||||||
ExFreePool(Driver);
|
ExFreePool(Driver);
|
||||||
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
GenericDriver = Driver;
|
GenericDriver = Driver;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -69,22 +64,18 @@ PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
|
||||||
|
|
||||||
/* First see if the driver hasn't already been loaded */
|
/* First see if the driver hasn't already been loaded */
|
||||||
while (Driver && Name)
|
while (Driver && Name)
|
||||||
|
{
|
||||||
|
if (!_wcsicmp( Driver->Name, Name))
|
||||||
{
|
{
|
||||||
if (!_wcsicmp( Driver->Name, Name))
|
return Driver->EnableDriver;
|
||||||
{
|
|
||||||
return Driver->EnableDriver;
|
|
||||||
}
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
}
|
||||||
|
Driver = Driver->Next;
|
||||||
|
}
|
||||||
|
|
||||||
/* If not, then load it */
|
/* If not, then load it */
|
||||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
RtlInitUnicodeString (&GdiDriverInfo.DriverName, (LPWSTR)Name);
|
||||||
(LPWSTR)Name);
|
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
if (!NT_SUCCESS(Status)) return NULL;
|
||||||
&GdiDriverInfo,
|
|
||||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
|
DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
|
||||||
return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
|
return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
|
||||||
|
@ -182,35 +173,31 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
|
||||||
PMP_DRIVERENTRY PMP_DriverEntry;
|
PMP_DRIVERENTRY PMP_DriverEntry;
|
||||||
|
|
||||||
/* Phase 1 */
|
/* Phase 1 */
|
||||||
RtlInitUnicodeString (&GdiDriverInfo.DriverName,
|
RtlInitUnicodeString (&GdiDriverInfo.DriverName, L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
|
||||||
L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
|
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
||||||
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
|
|
||||||
&GdiDriverInfo,
|
|
||||||
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Phase 2 */
|
/* Phase 2 */
|
||||||
if (Name[0] != '\\')
|
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) +
|
/* FIXME: Read this information from the registry ??? */
|
||||||
10 * sizeof(WCHAR));
|
wcscat(lName, L"DISPLAY1");
|
||||||
wcscpy(lName, L"\\??\\");
|
|
||||||
if (!wcscmp (Name, L"DISPLAY"))
|
|
||||||
{
|
|
||||||
/* FIXME: Read this information from the registry ??? */
|
|
||||||
wcscat(lName, L"DISPLAY1");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wcscat(lName, Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wcscat(lName, Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
|
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
|
||||||
wcscpy(lName, Name);
|
wcscpy(lName, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Phase 3 */
|
/* Phase 3 */
|
||||||
DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
|
DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
|
||||||
|
@ -234,44 +221,44 @@ BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
|
||||||
PGRAPHICS_DRIVER Driver = NULL;
|
PGRAPHICS_DRIVER Driver = NULL;
|
||||||
|
|
||||||
if (Name)
|
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 = Driver->Next;
|
||||||
{
|
|
||||||
Driver = DriverList;
|
|
||||||
DriverList = DriverList->Next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Driver = DriverList;
|
|
||||||
while (Driver->Next && _wcsicmp(Driver->Name, Name))
|
|
||||||
{
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (GenericDriver != NULL)
|
||||||
{
|
{
|
||||||
if (GenericDriver != NULL)
|
Driver = GenericDriver;
|
||||||
{
|
GenericDriver = NULL;
|
||||||
Driver = GenericDriver;
|
|
||||||
GenericDriver = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Driver != NULL)
|
if (Driver != NULL)
|
||||||
{
|
{
|
||||||
ExFreePool(Driver->Name);
|
ExFreePool(Driver->Name);
|
||||||
ExFreePool(Driver);
|
ExFreePool(Driver);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INT DRIVER_ReferenceDriver (LPCWSTR Name)
|
INT DRIVER_ReferenceDriver (LPCWSTR Name)
|
||||||
|
@ -279,14 +266,14 @@ INT DRIVER_ReferenceDriver (LPCWSTR Name)
|
||||||
GRAPHICS_DRIVER *Driver = DriverList;
|
GRAPHICS_DRIVER *Driver = DriverList;
|
||||||
|
|
||||||
while (Driver && Name)
|
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 );
|
return ++Driver->ReferenceCount;
|
||||||
if (!_wcsicmp( Driver->Name, Name))
|
|
||||||
{
|
|
||||||
return ++Driver->ReferenceCount;
|
|
||||||
}
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
}
|
||||||
|
Driver = Driver->Next;
|
||||||
|
}
|
||||||
DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
||||||
assert( GenericDriver != 0 );
|
assert( GenericDriver != 0 );
|
||||||
return ++GenericDriver->ReferenceCount;
|
return ++GenericDriver->ReferenceCount;
|
||||||
|
@ -297,14 +284,14 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name)
|
||||||
GRAPHICS_DRIVER *Driver = DriverList;
|
GRAPHICS_DRIVER *Driver = DriverList;
|
||||||
|
|
||||||
while (Driver && Name)
|
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 );
|
return --Driver->ReferenceCount;
|
||||||
if (!_wcsicmp( Driver->Name, Name))
|
|
||||||
{
|
|
||||||
return --Driver->ReferenceCount;
|
|
||||||
}
|
|
||||||
Driver = Driver->Next;
|
|
||||||
}
|
}
|
||||||
|
Driver = Driver->Next;
|
||||||
|
}
|
||||||
DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
|
||||||
assert( GenericDriver != 0 );
|
assert( GenericDriver != 0 );
|
||||||
return --GenericDriver->ReferenceCount;
|
return --GenericDriver->ReferenceCount;
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
* */
|
* */
|
||||||
|
|
||||||
#define BEZIERMIDDLE(Mid, P1, P2) \
|
#define BEZIERMIDDLE(Mid, P1, P2) \
|
||||||
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
(Mid).x=((P1).x+(P2).x + 1)/2;\
|
||||||
(Mid).y=((P1).y+(P2).y + 1)/2;
|
(Mid).y=((P1).y+(P2).y + 1)/2;
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* BezierCheck helper function to check
|
* BezierCheck helper function to check
|
||||||
|
@ -54,55 +54,46 @@
|
||||||
*/
|
*/
|
||||||
static BOOL BezierCheck( int level, POINT *Points)
|
static BOOL BezierCheck( int level, POINT *Points)
|
||||||
{
|
{
|
||||||
INT dx, dy;
|
INT dx, dy;
|
||||||
dx=Points[3].x-Points[0].x;
|
|
||||||
dy=Points[3].y-Points[0].y;
|
dx=Points[3].x-Points[0].x;
|
||||||
if(abs(dy)<=abs(dx)){/* shallow line */
|
dy=Points[3].y-Points[0].y;
|
||||||
/* check that control points are between begin and end */
|
if(abs(dy)<=abs(dx)) {/* shallow line */
|
||||||
if(Points[1].x < Points[0].x){
|
/* check that control points are between begin and end */
|
||||||
if(Points[1].x < Points[3].x)
|
if(Points[1].x < Points[0].x){
|
||||||
return FALSE;
|
if(Points[1].x < Points[3].x) return FALSE;
|
||||||
}else
|
}else
|
||||||
if(Points[1].x > Points[3].x)
|
if(Points[1].x > Points[3].x) return FALSE;
|
||||||
return FALSE;
|
if(Points[2].x < Points[0].x) {
|
||||||
if(Points[2].x < Points[0].x){
|
if(Points[2].x < Points[3].x) return FALSE;
|
||||||
if(Points[2].x < Points[3].x)
|
} else
|
||||||
return FALSE;
|
if(Points[2].x > Points[3].x) return FALSE;
|
||||||
}else
|
dx=BEZIERSHIFTDOWN(dx);
|
||||||
if(Points[2].x > Points[3].x)
|
if(!dx) return TRUE;
|
||||||
return FALSE;
|
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
||||||
dx=BEZIERSHIFTDOWN(dx);
|
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
||||||
if(!dx) return TRUE;
|
abs(Points[2].y-Points[0].y-(dy/dx)*
|
||||||
if(abs(Points[1].y-Points[0].y-(dy/dx)*
|
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL) return FALSE;
|
||||||
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
|
else
|
||||||
abs(Points[2].y-Points[0].y-(dy/dx)*
|
return TRUE;
|
||||||
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL )
|
} else{ /* steep line */
|
||||||
return FALSE;
|
/* check that control points are between begin and end */
|
||||||
else
|
if(Points[1].y < Points[0].y){
|
||||||
return TRUE;
|
if(Points[1].y < Points[3].y) return FALSE;
|
||||||
}else{ /* steep line */
|
} else
|
||||||
/* check that control points are between begin and end */
|
if(Points[1].y > Points[3].y) return FALSE;
|
||||||
if(Points[1].y < Points[0].y){
|
if(Points[2].y < Points[0].y){
|
||||||
if(Points[1].y < Points[3].y)
|
if(Points[2].y < Points[3].y) return FALSE;
|
||||||
return FALSE;
|
} else
|
||||||
}else
|
if(Points[2].y > Points[3].y) return FALSE;
|
||||||
if(Points[1].y > Points[3].y)
|
dy=BEZIERSHIFTDOWN(dy);
|
||||||
return FALSE;
|
if(!dy) return TRUE;
|
||||||
if(Points[2].y < Points[0].y){
|
if(abs(Points[1].x-Points[0].x-(dx/dy)*
|
||||||
if(Points[2].y < Points[3].y)
|
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
|
||||||
return FALSE;
|
abs(Points[2].x-Points[0].x-(dx/dy)*
|
||||||
}else
|
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL ) return FALSE;
|
||||||
if(Points[2].y > Points[3].y)
|
else
|
||||||
return FALSE;
|
return TRUE;
|
||||||
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,
|
static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
|
||||||
INT *nPtsOut, INT level )
|
INT *nPtsOut, INT level )
|
||||||
{
|
{
|
||||||
if(*nPtsOut == *dwOut) {
|
if(*nPtsOut == *dwOut) {
|
||||||
*dwOut *= 2;
|
*dwOut *= 2;
|
||||||
*PtsOut = ExAllocatePool(NonPagedPool, *dwOut * sizeof(POINT));
|
*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)) {
|
BEZIERMIDDLE(Points[1], Points[0], Points[1]);
|
||||||
if(*nPtsOut == 0) {
|
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
||||||
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
|
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
||||||
(*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]);
|
Points2[0]=Points[3];
|
||||||
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
|
|
||||||
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
|
|
||||||
|
|
||||||
Points2[0]=Points[3];
|
/* do the two halves */
|
||||||
|
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
|
||||||
/* do the two halves */
|
GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
|
||||||
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 *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
|
||||||
{
|
{
|
||||||
POINT *out;
|
POINT *out;
|
||||||
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
|
||||||
|
|
||||||
if((count - 1) % 3 != 0) {
|
if((count - 1) % 3 != 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*nPtsOut = 0;
|
*nPtsOut = 0;
|
||||||
out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
|
out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
|
||||||
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
|
||||||
POINT ptBuf[4];
|
POINT ptBuf[4];
|
||||||
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
|
||||||
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
|
||||||
}
|
|
||||||
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
|
||||||
}
|
}
|
||||||
|
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <win32k/bitmaps.h>
|
#include <win32k/bitmaps.h>
|
||||||
//#include <win32k/debug.h>
|
//#include <win32k/debug.h>
|
||||||
|
#include "../eng/objects.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -19,15 +18,19 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
|
||||||
INT YSrc,
|
INT YSrc,
|
||||||
DWORD ROP)
|
DWORD ROP)
|
||||||
{
|
{
|
||||||
PDC DCDest = DC_HandleToPtr(hDCDest);
|
PDC DCDest = DC_HandleToPtr(hDCDest);
|
||||||
PDC DCSrc = DC_HandleToPtr(hDCSrc);
|
PDC DCSrc = DC_HandleToPtr(hDCSrc);
|
||||||
PSURFOBJ SurfDest;
|
PSURFOBJ SurfDest, SurfSrc;
|
||||||
PSURFOBJ SurfSrc;
|
PSURFGDI SurfGDIDest, SurfGDISrc;
|
||||||
RECTL DestRect;
|
RECTL DestRect;
|
||||||
POINTL SourcePoint;
|
POINTL SourcePoint;
|
||||||
PBITMAPOBJ DestBitmapObj;
|
PBITMAPOBJ DestBitmapObj;
|
||||||
PBITMAPOBJ SrcBitmapObj;
|
PBITMAPOBJ SrcBitmapObj;
|
||||||
BOOL Status, SurfDestAlloc, SurfSrcAlloc;
|
BOOL Status, SurfDestAlloc, SurfSrcAlloc;
|
||||||
|
PPALOBJ DCLogPal;
|
||||||
|
PPALGDI PalDestGDI, PalSourceGDI;
|
||||||
|
PXLATEOBJ XlateObj = NULL;
|
||||||
|
HPALETTE SourcePalette, DestPalette;
|
||||||
|
|
||||||
DestRect.left = XDest;
|
DestRect.left = XDest;
|
||||||
DestRect.top = YDest;
|
DestRect.top = YDest;
|
||||||
|
@ -40,32 +43,44 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
|
||||||
SurfDestAlloc = FALSE;
|
SurfDestAlloc = FALSE;
|
||||||
SurfSrcAlloc = 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
|
SurfGDIDest = AccessInternalObjectFromUserObject(SurfDest);
|
||||||
if(DCDest->Surface != NULL)
|
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
|
if(DCDest->w.hPalette != 0)
|
||||||
SurfDest = AccessUserObject(DCDest->Surface);
|
{
|
||||||
} else
|
DestPalette = DCDest->w.hPalette;
|
||||||
return FALSE;
|
} 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
|
PalDestGDI = AccessInternalObject(DestPalette);
|
||||||
if(DCSrc->Surface != NULL)
|
PalSourceGDI = AccessInternalObject(SourcePalette);
|
||||||
{
|
|
||||||
DPRINT("from DC's surface\n");
|
|
||||||
|
|
||||||
// Use the DC's surface if it has one
|
XlateObj = EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette);
|
||||||
SurfSrc = AccessUserObject(DCSrc->Surface);
|
}
|
||||||
} else
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
|
// Perform the bitblt operation
|
||||||
|
|
||||||
DPRINT("Go to EngBitBlt\n");
|
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
|
||||||
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL,
|
|
||||||
&DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
|
|
||||||
|
|
||||||
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
|
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
|
||||||
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
|
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
|
||||||
|
@ -87,35 +102,35 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
|
||||||
|
|
||||||
/* Check parameters */
|
/* Check parameters */
|
||||||
if (!Height || !Width)
|
if (!Height || !Width)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (Planes != 1)
|
if (Planes != 1)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (Height < 0)
|
if (Height < 0)
|
||||||
{
|
{
|
||||||
Height = -Height;
|
Height = -Height;
|
||||||
}
|
}
|
||||||
if (Width < 0)
|
if (Width < 0)
|
||||||
{
|
{
|
||||||
Width = -Width;
|
Width = -Width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the BITMAPOBJ */
|
/* Create the BITMAPOBJ */
|
||||||
bmp = BITMAPOBJ_AllocBitmap ();
|
bmp = BITMAPOBJ_AllocBitmap ();
|
||||||
if (!bmp)
|
if (!bmp)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
|
DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
|
||||||
1 << (Planes * BitsPerPel), BitsPerPel, bmp);
|
1 << (Planes * BitsPerPel), BitsPerPel, bmp);
|
||||||
|
|
||||||
bmp->size.cx = 0;
|
bmp->size.cx = Width;
|
||||||
bmp->size.cy = 0;
|
bmp->size.cy = Height;
|
||||||
bmp->bitmap.bmType = 0;
|
bmp->bitmap.bmType = 0;
|
||||||
bmp->bitmap.bmWidth = Width;
|
bmp->bitmap.bmWidth = Width;
|
||||||
bmp->bitmap.bmHeight = Height;
|
bmp->bitmap.bmHeight = Height;
|
||||||
|
@ -131,12 +146,9 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
|
||||||
bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
|
bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
|
||||||
|
|
||||||
if (Bits) /* Set bitmap bits */
|
if (Bits) /* Set bitmap bits */
|
||||||
{
|
{
|
||||||
W32kSetBitmapBits(hBitmap,
|
W32kSetBitmapBits(hBitmap, Height * bmp->bitmap.bmWidthBytes, Bits);
|
||||||
Height * bmp->bitmap.bmWidthBytes,
|
}
|
||||||
Bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return hBitmap;
|
return hBitmap;
|
||||||
}
|
}
|
||||||
|
@ -151,33 +163,28 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
|
||||||
hbmpRet = 0;
|
hbmpRet = 0;
|
||||||
dc = DC_HandleToPtr (hDC);
|
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)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((Width >= 0x10000) || (Height >= 0x10000))
|
if ((Width >= 0x10000) || (Height >= 0x10000))
|
||||||
{
|
{
|
||||||
DPRINT("got bad width %d or height %d, please look for reason\n",
|
DPRINT("got bad width %d or height %d, please look for reason\n", Width, Height);
|
||||||
Width, Height);
|
}
|
||||||
}
|
|
||||||
else
|
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 */
|
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
|
||||||
if (!Width || !Height)
|
|
||||||
{
|
|
||||||
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hbmpRet = W32kCreateBitmap (Width,
|
|
||||||
Height,
|
|
||||||
1,
|
|
||||||
dc->w.bitsPerPixel,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hbmpRet = W32kCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
DPRINT ("\t\t%04x\n", hbmpRet);
|
DPRINT ("\t\t%04x\n", hbmpRet);
|
||||||
DC_UnlockDC (hDC);
|
DC_UnlockDC (hDC);
|
||||||
|
|
||||||
|
@ -193,26 +200,6 @@ HBITMAP STDCALL W32kCreateBitmapIndirect(CONST BITMAP *BM)
|
||||||
BM->bmBits);
|
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,
|
HBITMAP STDCALL W32kCreateDiscardableBitmap(HDC hDC,
|
||||||
INT Width,
|
INT Width,
|
||||||
INT Height)
|
INT Height)
|
||||||
|
@ -238,83 +225,6 @@ BOOL STDCALL W32kFloodFill(HDC hDC,
|
||||||
UNIMPLEMENTED;
|
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,
|
BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
||||||
LPSIZE Dimension)
|
LPSIZE Dimension)
|
||||||
{
|
{
|
||||||
|
@ -322,9 +232,9 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
||||||
|
|
||||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||||
if (bmp == NULL)
|
if (bmp == NULL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*Dimension = bmp->size;
|
*Dimension = bmp->size;
|
||||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||||
|
@ -332,25 +242,6 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
||||||
return TRUE;
|
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,
|
COLORREF STDCALL W32kGetPixel(HDC hDC,
|
||||||
INT XPos,
|
INT XPos,
|
||||||
INT YPos)
|
INT YPos)
|
||||||
|
@ -397,22 +288,22 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
|
||||||
|
|
||||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||||
if (bmp == NULL || Bits == NULL)
|
if (bmp == NULL || Bits == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Bytes < 0)
|
if (Bytes < 0)
|
||||||
{
|
{
|
||||||
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
|
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
|
||||||
Bytes = -Bytes;
|
Bytes = -Bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only get entire lines */
|
/* Only get entire lines */
|
||||||
height = Bytes / bmp->bitmap.bmWidthBytes;
|
height = Bytes / bmp->bitmap.bmWidthBytes;
|
||||||
if (height > bmp->bitmap.bmHeight)
|
if (height > bmp->bitmap.bmHeight)
|
||||||
{
|
{
|
||||||
height = bmp->bitmap.bmHeight;
|
height = bmp->bitmap.bmHeight;
|
||||||
}
|
}
|
||||||
Bytes = height * bmp->bitmap.bmWidthBytes;
|
Bytes = height * bmp->bitmap.bmWidthBytes;
|
||||||
DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
|
DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
|
||||||
hBitmap,
|
hBitmap,
|
||||||
|
@ -426,39 +317,36 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
|
||||||
#if 0
|
#if 0
|
||||||
/* FIXME: call DDI specific function here if available */
|
/* FIXME: call DDI specific function here if available */
|
||||||
if(bmp->DDBitmap)
|
if(bmp->DDBitmap)
|
||||||
|
{
|
||||||
|
DPRINT ("Calling device specific BitmapBits\n");
|
||||||
|
if (bmp->DDBitmap->funcs->pBitmapBits)
|
||||||
{
|
{
|
||||||
DPRINT ("Calling device specific BitmapBits\n");
|
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
|
||||||
if (bmp->DDBitmap->funcs->pBitmapBits)
|
|
||||||
{
|
|
||||||
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap,
|
|
||||||
(void *) Bits,
|
|
||||||
Bytes,
|
|
||||||
DDB_SET);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT ("BitmapBits == NULL??\n");
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT ("BitmapBits == NULL??\n");
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* FIXME: Alloc enough for entire bitmap */
|
/* FIXME: Alloc enough for entire bitmap */
|
||||||
if (bmp->bitmap.bmBits == NULL)
|
if (bmp->bitmap.bmBits == NULL)
|
||||||
{
|
{
|
||||||
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
|
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
|
||||||
}
|
}
|
||||||
if(!bmp->bitmap.bmBits)
|
if(!bmp->bitmap.bmBits)
|
||||||
{
|
{
|
||||||
DPRINT ("Unable to allocate bit buffer\n");
|
DPRINT ("Unable to allocate bit buffer\n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(bmp->bitmap.bmBits, Bits, Bytes);
|
memcpy(bmp->bitmap.bmBits, Bits, Bytes);
|
||||||
ret = Bytes;
|
ret = Bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||||
|
|
||||||
|
@ -474,14 +362,14 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
|
||||||
|
|
||||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||||
if (bmp == NULL)
|
if (bmp == NULL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Size)
|
if (Size)
|
||||||
{
|
{
|
||||||
*Size = bmp->size;
|
*Size = bmp->size;
|
||||||
}
|
}
|
||||||
bmp->size.cx = Width;
|
bmp->size.cx = Width;
|
||||||
bmp->size.cy = Height;
|
bmp->size.cy = Height;
|
||||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||||
|
@ -489,41 +377,6 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
|
||||||
return TRUE;
|
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,
|
COLORREF STDCALL W32kSetPixel(HDC hDC,
|
||||||
INT X,
|
INT X,
|
||||||
INT Y,
|
INT Y,
|
||||||
|
@ -555,30 +408,13 @@ BOOL STDCALL W32kStretchBlt(HDC hDCDest,
|
||||||
UNIMPLEMENTED;
|
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 */
|
/* Internal Functions */
|
||||||
|
|
||||||
INT
|
INT
|
||||||
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
|
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
|
||||||
{
|
{
|
||||||
switch(bpp)
|
switch(bpp)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return 2 * ((bmWidth+15) >> 4);
|
return 2 * ((bmWidth+15) >> 4);
|
||||||
|
|
||||||
|
@ -599,7 +435,7 @@ BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINT ("stub");
|
DPRINT ("stub");
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -612,94 +448,47 @@ HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
|
||||||
|
|
||||||
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
|
||||||
if (bmp == NULL)
|
if (bmp == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
bm = bmp->bitmap;
|
bm = bmp->bitmap;
|
||||||
bm.bmBits = NULL;
|
bm.bmBits = NULL;
|
||||||
res = W32kCreateBitmapIndirect(&bm);
|
res = W32kCreateBitmapIndirect(&bm);
|
||||||
if(res)
|
if(res)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
|
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
|
||||||
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
|
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||||
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
|
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||||
ExFreePool (buf);
|
ExFreePool (buf);
|
||||||
}
|
}
|
||||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
INT BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer)
|
||||||
* 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;
|
if(bmp->dib)
|
||||||
|
{
|
||||||
switch(depth)
|
if(count < sizeof(DIBSECTION))
|
||||||
{
|
{
|
||||||
case 1: words = (width + 31) / 32; break;
|
if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
|
||||||
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;
|
else
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* 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;
|
if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
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;
|
PBRUSHOBJ brushPtr;
|
||||||
HBRUSH hBrush;
|
HBRUSH hBrush;
|
||||||
|
|
||||||
hBrush = BRUSHOBJ_AllocBrush ();
|
brushPtr = BRUSHOBJ_AllocBrush();
|
||||||
|
hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
|
||||||
if (hBrush == NULL)
|
if (hBrush == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
brushPtr = BRUSHOBJ_HandleToPtr (hBrush);
|
|
||||||
brushPtr->logbrush.lbStyle = lb->lbStyle;
|
brushPtr->logbrush.lbStyle = lb->lbStyle;
|
||||||
brushPtr->logbrush.lbColor = lb->lbColor;
|
brushPtr->logbrush.lbColor = lb->lbColor;
|
||||||
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
||||||
|
|
||||||
BRUSHOBJ_UnlockBrush (hBrush);
|
BRUSHOBJ_UnlockBrush (hBrush);
|
||||||
DPRINT("%08x\n", hBrush);
|
DPRINT("%08x\n", hBrush);
|
||||||
|
|
||||||
|
@ -50,29 +51,26 @@ HBRUSH STDCALL W32kCreateDIBPatternBrush(HGLOBAL hDIBPacked,
|
||||||
|
|
||||||
/* Make a copy of the bitmap */
|
/* Make a copy of the bitmap */
|
||||||
if (!(info = (BITMAPINFO *)GlobalLock( hbitmap )))
|
if (!(info = (BITMAPINFO *)GlobalLock( hbitmap )))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (info->bmiHeader.biCompression)
|
if (info->bmiHeader.biCompression) size = info->bmiHeader.biSizeImage;
|
||||||
size = info->bmiHeader.biSizeImage;
|
else
|
||||||
else
|
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
|
||||||
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
|
size += DIB_BitmapInfoSize(info, coloruse);
|
||||||
info->bmiHeader.biHeight,
|
|
||||||
info->bmiHeader.biBitCount);
|
|
||||||
size += DIB_BitmapInfoSize( info, coloruse );
|
|
||||||
|
|
||||||
if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
|
if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
|
||||||
{
|
{
|
||||||
GlobalUnlock16( hbitmap );
|
GlobalUnlock16( hbitmap );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch );
|
newInfo = (BITMAPINFO *) GlobalLock16((HGLOBAL16)logbrush.lbHatch);
|
||||||
memcpy( newInfo, info, size );
|
memcpy(newInfo, info, size);
|
||||||
GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch );
|
GlobalUnlock16((HGLOBAL16)logbrush.lbHatch);
|
||||||
GlobalUnlock( hbitmap );
|
GlobalUnlock(hbitmap);
|
||||||
return W32kCreateBrushIndirect( &logbrush );
|
return W32kCreateBrushIndirect(&logbrush);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +84,9 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
|
||||||
|
|
||||||
info = (BITMAPINFO *) PackedDIB;
|
info = (BITMAPINFO *) PackedDIB;
|
||||||
if (info == NULL)
|
if (info == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DPRINT ("%p %ldx%ld %dbpp\n",
|
DPRINT ("%p %ldx%ld %dbpp\n",
|
||||||
info,
|
info,
|
||||||
info->bmiHeader.biWidth,
|
info->bmiHeader.biWidth,
|
||||||
|
@ -102,28 +100,23 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
|
||||||
/* Make a copy of the bitmap */
|
/* Make a copy of the bitmap */
|
||||||
|
|
||||||
if (info->bmiHeader.biCompression)
|
if (info->bmiHeader.biCompression)
|
||||||
{
|
{
|
||||||
size = info->bmiHeader.biSizeImage;
|
size = info->bmiHeader.biSizeImage;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth,
|
size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
|
||||||
info->bmiHeader.biHeight,
|
}
|
||||||
info->bmiHeader.biBitCount);
|
|
||||||
}
|
|
||||||
size += DIB_BitmapInfoSize (info, Usage);
|
size += DIB_BitmapInfoSize (info, Usage);
|
||||||
|
|
||||||
logbrush.lbHatch = (INT)
|
logbrush.lbHatch = (INT)GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE), GO_MAGIC_DONTCARE);
|
||||||
GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE),
|
|
||||||
GO_MAGIC_DONTCARE);
|
|
||||||
if (logbrush.lbHatch == 0)
|
if (logbrush.lbHatch == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch,
|
newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch, GO_MAGIC_DONTCARE);
|
||||||
GO_MAGIC_DONTCARE);
|
memcpy(newInfo, info, size);
|
||||||
memcpy (newInfo, info, size);
|
GDIOBJ_UnlockObject((HGDIOBJ)logbrush.lbHatch);
|
||||||
GDIOBJ_UnlockObject ((HGDIOBJ) logbrush.lbHatch);
|
|
||||||
|
|
||||||
return W32kCreateBrushIndirect (&logbrush);
|
return W32kCreateBrushIndirect (&logbrush);
|
||||||
}
|
}
|
||||||
|
@ -136,9 +129,9 @@ HBRUSH STDCALL W32kCreateHatchBrush(INT Style,
|
||||||
DPRINT("%d %06lx\n", Style, Color);
|
DPRINT("%d %06lx\n", Style, Color);
|
||||||
|
|
||||||
if (Style < 0 || Style >= NB_HATCH_STYLES)
|
if (Style < 0 || Style >= NB_HATCH_STYLES)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
logbrush.lbStyle = BS_HATCHED;
|
logbrush.lbStyle = BS_HATCHED;
|
||||||
logbrush.lbColor = Color;
|
logbrush.lbColor = Color;
|
||||||
logbrush.lbHatch = Style;
|
logbrush.lbHatch = Style;
|
||||||
|
@ -153,24 +146,24 @@ HBRUSH STDCALL W32kCreatePatternBrush(HBITMAP hBitmap)
|
||||||
DPRINT ("%04x\n", hBitmap);
|
DPRINT ("%04x\n", hBitmap);
|
||||||
logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap);
|
logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap);
|
||||||
if(!logbrush.lbHatch)
|
if(!logbrush.lbHatch)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return W32kCreateBrushIndirect( &logbrush );
|
return W32kCreateBrushIndirect( &logbrush );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HBRUSH STDCALL W32kCreateSolidBrush(COLORREF Color)
|
HBRUSH STDCALL W32kCreateSolidBrush(COLORREF Color)
|
||||||
{
|
{
|
||||||
LOGBRUSH logbrush;
|
LOGBRUSH logbrush;
|
||||||
|
|
||||||
logbrush.lbStyle = BS_SOLID;
|
logbrush.lbStyle = BS_SOLID;
|
||||||
logbrush.lbColor = Color;
|
logbrush.lbColor = Color;
|
||||||
logbrush.lbHatch = 0;
|
logbrush.lbHatch = 0;
|
||||||
|
|
||||||
return W32kCreateBrushIndirect(&logbrush);
|
return W32kCreateBrushIndirect(&logbrush);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL STDCALL W32kFixBrushOrgEx(VOID)
|
BOOL STDCALL W32kFixBrushOrgEx(VOID)
|
||||||
|
|
|
@ -1,28 +1,135 @@
|
||||||
|
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
#include <ddk/winddi.h>
|
||||||
|
#include <win32k/dc.h>
|
||||||
#include <win32k/color.h>
|
#include <win32k/color.h>
|
||||||
|
#include "../eng/objects.h"
|
||||||
|
|
||||||
// #define NDEBUG
|
// #define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#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,
|
BOOL STDCALL W32kAnimatePalette(HPALETTE hpal,
|
||||||
UINT StartIndex,
|
UINT StartIndex,
|
||||||
UINT Entries,
|
UINT Entries,
|
||||||
CONST PPALETTEENTRY ppe)
|
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;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
HPALETTE STDCALL W32kCreateHalftonePalette(HDC hDC)
|
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,
|
BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
|
||||||
|
@ -34,13 +141,43 @@ BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
|
||||||
COLORREF STDCALL W32kGetNearestColor(HDC hDC,
|
COLORREF STDCALL W32kGetNearestColor(HDC hDC,
|
||||||
COLORREF Color)
|
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,
|
UINT STDCALL W32kGetNearestPaletteIndex(HPALETTE hpal,
|
||||||
COLORREF Color)
|
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,
|
UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
|
||||||
|
@ -48,7 +185,29 @@ UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
|
||||||
UINT Entries,
|
UINT Entries,
|
||||||
LPPALETTEENTRY pe)
|
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,
|
UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
|
||||||
|
@ -56,7 +215,33 @@ UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
|
||||||
UINT Entries,
|
UINT Entries,
|
||||||
LPPALETTEENTRY pe)
|
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)
|
UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
|
||||||
|
@ -65,13 +250,112 @@ UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT STDCALL W32kRealizePalette(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,
|
BOOL STDCALL W32kResizePalette(HPALETTE hpal,
|
||||||
UINT Entries)
|
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;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +363,15 @@ HPALETTE STDCALL W32kSelectPalette(HDC hDC,
|
||||||
HPALETTE hpal,
|
HPALETTE hpal,
|
||||||
BOOL ForceBackground)
|
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,
|
BOOL STDCALL W32kSetColorAdjustment(HDC hDC,
|
||||||
|
@ -93,7 +385,25 @@ UINT STDCALL W32kSetPaletteEntries(HPALETTE hpal,
|
||||||
UINT Entries,
|
UINT Entries,
|
||||||
CONST LPPALETTEENTRY pe)
|
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,
|
UINT STDCALL W32kSetSystemPaletteUse(HDC hDC,
|
||||||
|
@ -109,6 +419,81 @@ BOOL STDCALL W32kUnrealizeObject(HGDIOBJ hgdiobj)
|
||||||
|
|
||||||
BOOL STDCALL W32kUpdateColors(HDC hDC)
|
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 */
|
/* Check for illegal parameters */
|
||||||
if (!XFormResult || !xform1 || !xform2)
|
if (!XFormResult || !xform1 || !xform2)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* Create the result in a temporary XFORM, since xformResult may be
|
/* Create the result in a temporary XFORM, since xformResult may be
|
||||||
* equal to xform1 or xform2 */
|
* equal to xform1 or xform2 */
|
||||||
xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
|
xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
|
||||||
xform1->eM12 * xform2->eM21;
|
xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
|
||||||
xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
|
xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
|
||||||
xform1->eM12 * xform2->eM22;
|
xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
|
||||||
xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
|
xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
|
||||||
xform1->eM22 * xform2->eM21;
|
xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
|
||||||
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 */
|
/* Copy the result to xformResult */
|
||||||
*XFormResult = xformTemp;
|
*XFormResult = xformTemp;
|
||||||
|
@ -57,9 +51,9 @@ W32kGetGraphicsMode(HDC hDC)
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsMode = dc->w.GraphicsMode;
|
GraphicsMode = dc->w.GraphicsMode;
|
||||||
DC_UnlockDC (hDC);
|
DC_UnlockDC (hDC);
|
||||||
|
@ -76,13 +70,13 @@ W32kGetWorldTransform(HDC hDC,
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!XForm)
|
if (!XForm)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*XForm = dc->w.xformWorld2Wnd;
|
*XForm = dc->w.xformWorld2Wnd;
|
||||||
DC_UnlockDC (hDC);
|
DC_UnlockDC (hDC);
|
||||||
|
|
||||||
|
@ -108,22 +102,22 @@ W32kModifyWorldTransform(HDC hDC,
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
// SetLastError( ERROR_INVALID_HANDLE );
|
// SetLastError( ERROR_INVALID_HANDLE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!XForm)
|
if (!XForm)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that graphics mode is GM_ADVANCED */
|
/* Check that graphics mode is GM_ADVANCED */
|
||||||
if (dc->w.GraphicsMode!=GM_ADVANCED)
|
if (dc->w.GraphicsMode!=GM_ADVANCED)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
switch (Mode)
|
switch (Mode)
|
||||||
{
|
{
|
||||||
case MWT_IDENTITY:
|
case MWT_IDENTITY:
|
||||||
dc->w.xformWorld2Wnd.eM11 = 1.0f;
|
dc->w.xformWorld2Wnd.eM11 = 1.0f;
|
||||||
dc->w.xformWorld2Wnd.eM12 = 0.0f;
|
dc->w.xformWorld2Wnd.eM12 = 0.0f;
|
||||||
|
@ -134,20 +128,16 @@ W32kModifyWorldTransform(HDC hDC,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MWT_LEFTMULTIPLY:
|
case MWT_LEFTMULTIPLY:
|
||||||
W32kCombineTransform(&dc->w.xformWorld2Wnd,
|
W32kCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd );
|
||||||
XForm,
|
|
||||||
&dc->w.xformWorld2Wnd );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MWT_RIGHTMULTIPLY:
|
case MWT_RIGHTMULTIPLY:
|
||||||
W32kCombineTransform(&dc->w.xformWorld2Wnd,
|
W32kCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm);
|
||||||
&dc->w.xformWorld2Wnd,
|
|
||||||
XForm);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
DC_UpdateXforms (dc);
|
DC_UpdateXforms (dc);
|
||||||
DC_UnlockDC (hDC);
|
DC_UnlockDC (hDC);
|
||||||
|
|
||||||
|
@ -208,9 +198,9 @@ W32kSetGraphicsMode(HDC hDC,
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One would think that setting the graphics mode to GM_COMPATIBLE
|
/* One would think that setting the graphics mode to GM_COMPATIBLE
|
||||||
* would also reset the world transformation matrix to the unity
|
* would also reset the world transformation matrix to the unity
|
||||||
|
@ -219,9 +209,9 @@ W32kSetGraphicsMode(HDC hDC,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
|
if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = dc->w.GraphicsMode;
|
ret = dc->w.GraphicsMode;
|
||||||
dc->w.GraphicsMode = Mode;
|
dc->w.GraphicsMode = Mode;
|
||||||
DC_UnlockDC (hDC);
|
DC_UnlockDC (hDC);
|
||||||
|
@ -286,20 +276,20 @@ W32kSetWorldTransform(HDC hDC,
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
// SetLastError( ERROR_INVALID_HANDLE );
|
// SetLastError( ERROR_INVALID_HANDLE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!XForm)
|
if (!XForm)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that graphics mode is GM_ADVANCED */
|
/* Check that graphics mode is GM_ADVANCED */
|
||||||
if (dc->w.GraphicsMode != GM_ADVANCED)
|
if (dc->w.GraphicsMode != GM_ADVANCED)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
dc->w.xformWorld2Wnd = *XForm;
|
dc->w.xformWorld2Wnd = *XForm;
|
||||||
DC_UpdateXforms (dc);
|
DC_UpdateXforms (dc);
|
||||||
DC_UnlockDC (hDC);
|
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 RightRect,
|
||||||
int BottomRect)
|
int BottomRect)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||||
PBRUSHOBJ BrushObj;
|
PBRUSHOBJ BrushObj;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
PRECTL RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
PRECTL RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
||||||
|
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path)) {
|
if(PATH_IsPathOpen(dc->w.path)) {
|
||||||
ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
|
ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
DbgPrint("W32kRectangle pen: ");
|
DbgPrint("W32kRectangle pen: ");
|
||||||
DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
|
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,
|
ret = EngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
NULL, // ClipObj,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
LeftRect, TopRect, RightRect, TopRect,
|
LeftRect, TopRect, RightRect, TopRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX
|
dc->w.ROPmode); // MIX
|
||||||
|
|
||||||
ret = EngLineTo(SurfObj,
|
ret = EngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
NULL, // ClipObj,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
RightRect, TopRect, RightRect, BottomRect,
|
RightRect, TopRect, RightRect, BottomRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX
|
dc->w.ROPmode); // MIX
|
||||||
|
|
||||||
ret = EngLineTo(SurfObj,
|
ret = EngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
NULL, // ClipObj,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
LeftRect, BottomRect, RightRect, BottomRect,
|
LeftRect, BottomRect, RightRect, BottomRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX
|
dc->w.ROPmode); // MIX
|
||||||
|
|
||||||
ret = EngLineTo(SurfObj,
|
ret = EngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
NULL, // ClipObj,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
LeftRect, TopRect, LeftRect, BottomRect,
|
LeftRect, TopRect, LeftRect, BottomRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX */
|
dc->w.ROPmode); // MIX */
|
||||||
|
|
||||||
ExFreePool(BrushObj);
|
ExFreePool(BrushObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Move current position in DC?
|
// FIXME: Move current position in DC?
|
||||||
|
|
||||||
|
@ -142,5 +142,3 @@ W32kRoundRect(HDC hDC,
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* GDIOBJ.C - GDI object manipulation routines
|
* 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,18 +9,107 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <win32k/gdiobj.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)
|
PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic)
|
||||||
{
|
{
|
||||||
PGDIOBJHDR NewObj;
|
PGDIOBJHDR NewObj;
|
||||||
|
|
||||||
NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
|
NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
|
||||||
|
|
||||||
if (NewObj == NULL)
|
if (NewObj == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
|
RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
|
||||||
|
|
||||||
NewObj->wMagic = Magic;
|
NewObj->wMagic = Magic;
|
||||||
#if 0
|
#if 0
|
||||||
KeInitializeSpinlock(&NewObj->Lock);
|
KeInitializeSpinlock(&NewObj->Lock);
|
||||||
|
@ -35,9 +124,9 @@ BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
|
||||||
|
|
||||||
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||||
if (ObjHdr->wMagic != Magic)
|
if (ObjHdr->wMagic != Magic)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
ExFreePool (ObjHdr);
|
ExFreePool (ObjHdr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +138,9 @@ HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
|
||||||
if (Obj == NULL) return NULL;
|
if (Obj == NULL) return NULL;
|
||||||
objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||||
if (objHeader->wMagic != Magic)
|
if (objHeader->wMagic != Magic)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (HGDIOBJ) objHeader;
|
return (HGDIOBJ) objHeader;
|
||||||
}
|
}
|
||||||
|
@ -67,9 +156,9 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
|
||||||
/* FIXME: Lock object for duration */
|
/* FIXME: Lock object for duration */
|
||||||
|
|
||||||
if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
|
if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
|
return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
|
||||||
}
|
}
|
||||||
|
@ -77,7 +166,7 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
|
||||||
BOOL GDIOBJ_LockObject (HGDIOBJ Obj)
|
BOOL GDIOBJ_LockObject (HGDIOBJ Obj)
|
||||||
{
|
{
|
||||||
/* FIXME: write this */
|
/* FIXME: write this */
|
||||||
return TRUE;
|
// return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj)
|
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj)
|
||||||
|
@ -92,9 +181,9 @@ HGDIOBJ GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic)
|
||||||
|
|
||||||
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
||||||
if (objHeader->wMagic != Magic)
|
if (objHeader->wMagic != Magic)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return objHeader->hNext;
|
return objHeader->hNext;
|
||||||
}
|
}
|
||||||
|
@ -107,14 +196,48 @@ HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj)
|
||||||
/* FIXME: should we lock/unlock the object here? */
|
/* FIXME: should we lock/unlock the object here? */
|
||||||
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
||||||
if (objHeader->wMagic != Magic)
|
if (objHeader->wMagic != Magic)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
oldNext = objHeader->hNext;
|
oldNext = objHeader->hNext;
|
||||||
objHeader->hNext = NextObj;
|
objHeader->hNext = NextObj;
|
||||||
|
|
||||||
return oldNext;
|
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 XEndArc,
|
||||||
int YEndArc)
|
int YEndArc)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path))
|
if(PATH_IsPathOpen(dc->w.path))
|
||||||
return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
||||||
XStartArc, YStartArc, XEndArc, YEndArc);
|
XStartArc, YStartArc, XEndArc, YEndArc);
|
||||||
|
|
||||||
// EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
|
// EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
|
||||||
// XStartArc, YStartArc, XEndArc, YEndArc);
|
// XStartArc, YStartArc, XEndArc, YEndArc);
|
||||||
|
@ -58,43 +58,43 @@ W32kArcTo(HDC hDC,
|
||||||
int XRadial2,
|
int XRadial2,
|
||||||
int YRadial2)
|
int YRadial2)
|
||||||
{
|
{
|
||||||
BOOL result;
|
BOOL result;
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
// Line from current position to starting point of arc
|
// Line from current position to starting point of arc
|
||||||
W32kLineTo(hDC, XRadial1, YRadial1);
|
W32kLineTo(hDC, XRadial1, YRadial1);
|
||||||
|
|
||||||
// Then the arc is drawn.
|
// Then the arc is drawn.
|
||||||
result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
|
||||||
XRadial1, YRadial1, XRadial2, YRadial2);
|
XRadial1, YRadial1, XRadial2, YRadial2);
|
||||||
|
|
||||||
// If no error occured, the current position is moved to the ending point of the arc.
|
// If no error occured, the current position is moved to the ending point of the arc.
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
|
W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT
|
INT
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kGetArcDirection(HDC hDC)
|
W32kGetArcDirection(HDC hDC)
|
||||||
{
|
{
|
||||||
PDC dc;
|
PDC dc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dc->w.ArcDirection;
|
ret = dc->w.ArcDirection;
|
||||||
DC_UnlockDC (hDC);
|
DC_UnlockDC (hDC);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -103,32 +103,28 @@ W32kLineTo(HDC hDC,
|
||||||
int XEnd,
|
int XEnd,
|
||||||
int YEnd)
|
int YEnd)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path)) {
|
if(PATH_IsPathOpen(dc->w.path)) {
|
||||||
ret = PATH_LineTo(hDC, XEnd, YEnd);
|
ret = PATH_LineTo(hDC, XEnd, YEnd);
|
||||||
} else {
|
} 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);
|
return ret;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -138,21 +134,21 @@ W32kMoveToEx(HDC hDC,
|
||||||
int Y,
|
int Y,
|
||||||
LPPOINT Point)
|
LPPOINT Point)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr( hDC );
|
DC *dc = DC_HandleToPtr( hDC );
|
||||||
|
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(Point) {
|
if(Point) {
|
||||||
Point->x = dc->w.CursPosX;
|
Point->x = dc->w.CursPosX;
|
||||||
Point->y = dc->w.CursPosY;
|
Point->y = dc->w.CursPosY;
|
||||||
}
|
}
|
||||||
dc->w.CursPosX = X;
|
dc->w.CursPosX = X;
|
||||||
dc->w.CursPosY = Y;
|
dc->w.CursPosY = Y;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path))
|
if(PATH_IsPathOpen(dc->w.path))
|
||||||
return PATH_MoveTo(hDC);
|
return PATH_MoveTo(hDC);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -161,25 +157,25 @@ W32kPolyBezier(HDC hDC,
|
||||||
CONST LPPOINT pt,
|
CONST LPPOINT pt,
|
||||||
DWORD Count)
|
DWORD Count)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path))
|
if(PATH_IsPathOpen(dc->w.path))
|
||||||
return PATH_PolyBezier(hDC, pt, Count);
|
return PATH_PolyBezier(hDC, pt, Count);
|
||||||
|
|
||||||
/* We'll convert it into line segments and draw them using Polyline */
|
/* We'll convert it into line segments and draw them using Polyline */
|
||||||
{
|
{
|
||||||
POINT *Pts;
|
POINT *Pts;
|
||||||
INT nOut;
|
INT nOut;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
Pts = GDI_Bezier(pt, Count, &nOut);
|
Pts = GDI_Bezier(pt, Count, &nOut);
|
||||||
if(!Pts) return FALSE;
|
if(!Pts) return FALSE;
|
||||||
DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
|
DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
|
||||||
ret = W32kPolyline(dc->hSelf, Pts, nOut);
|
ret = W32kPolyline(dc->hSelf, Pts, nOut);
|
||||||
ExFreePool(Pts);
|
ExFreePool(Pts);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -188,28 +184,28 @@ W32kPolyBezierTo(HDC hDC,
|
||||||
CONST LPPOINT pt,
|
CONST LPPOINT pt,
|
||||||
DWORD Count)
|
DWORD Count)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path))
|
if(PATH_IsPathOpen(dc->w.path))
|
||||||
ret = PATH_PolyBezierTo(hDC, pt, Count);
|
ret = PATH_PolyBezierTo(hDC, pt, Count);
|
||||||
else { /* We'll do it using PolyBezier */
|
else { /* We'll do it using PolyBezier */
|
||||||
POINT *npt;
|
POINT *npt;
|
||||||
npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
||||||
if(!npt) return FALSE;
|
if(!npt) return FALSE;
|
||||||
npt[0].x = dc->w.CursPosX;
|
npt[0].x = dc->w.CursPosX;
|
||||||
npt[0].y = dc->w.CursPosY;
|
npt[0].y = dc->w.CursPosY;
|
||||||
memcpy(npt + 1, pt, sizeof(POINT) * Count);
|
memcpy(npt + 1, pt, sizeof(POINT) * Count);
|
||||||
ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
|
ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
|
||||||
ExFreePool(npt);
|
ExFreePool(npt);
|
||||||
}
|
}
|
||||||
if(ret) {
|
if(ret) {
|
||||||
dc->w.CursPosX = pt[Count-1].x;
|
dc->w.CursPosX = pt[Count-1].x;
|
||||||
dc->w.CursPosY = pt[Count-1].y;
|
dc->w.CursPosY = pt[Count-1].y;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -237,30 +233,30 @@ W32kPolylineTo(HDC hDC,
|
||||||
CONST LPPOINT pt,
|
CONST LPPOINT pt,
|
||||||
DWORD Count)
|
DWORD Count)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
if(!dc) return FALSE;
|
if(!dc) return FALSE;
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path))
|
if(PATH_IsPathOpen(dc->w.path))
|
||||||
{
|
{
|
||||||
ret = PATH_PolylineTo(hDC, pt, Count);
|
ret = PATH_PolylineTo(hDC, pt, Count);
|
||||||
}
|
}
|
||||||
else { /* do it using Polyline */
|
else { /* do it using Polyline */
|
||||||
POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
|
||||||
if(!pts) return FALSE;
|
if(!pts) return FALSE;
|
||||||
|
|
||||||
pts[0].x = dc->w.CursPosX;
|
pts[0].x = dc->w.CursPosX;
|
||||||
pts[0].y = dc->w.CursPosY;
|
pts[0].y = dc->w.CursPosY;
|
||||||
memcpy( pts + 1, pt, sizeof(POINT) * Count);
|
memcpy( pts + 1, pt, sizeof(POINT) * Count);
|
||||||
ret = W32kPolyline(hDC, pts, Count + 1);
|
ret = W32kPolyline(hDC, pts, Count + 1);
|
||||||
ExFreePool(pts);
|
ExFreePool(pts);
|
||||||
}
|
}
|
||||||
if(ret) {
|
if(ret) {
|
||||||
dc->w.CursPosX = pt[Count-1].x;
|
dc->w.CursPosX = pt[Count-1].x;
|
||||||
dc->w.CursPosY = pt[Count-1].y;
|
dc->w.CursPosY = pt[Count-1].y;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -278,22 +274,22 @@ STDCALL
|
||||||
W32kSetArcDirection(HDC hDC,
|
W32kSetArcDirection(HDC hDC,
|
||||||
int ArcDirection)
|
int ArcDirection)
|
||||||
{
|
{
|
||||||
PDC dc;
|
PDC dc;
|
||||||
INT nOldDirection;
|
INT nOldDirection;
|
||||||
|
|
||||||
dc = DC_HandleToPtr (hDC);
|
dc = DC_HandleToPtr (hDC);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
|
if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
|
||||||
{
|
{
|
||||||
// SetLastError(ERROR_INVALID_PARAMETER);
|
// SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nOldDirection = dc->w.ArcDirection;
|
nOldDirection = dc->w.ArcDirection;
|
||||||
dc->w.ArcDirection = ArcDirection;
|
dc->w.ArcDirection = ArcDirection;
|
||||||
|
|
||||||
return nOldDirection;
|
return nOldDirection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,42 +15,38 @@
|
||||||
|
|
||||||
PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
|
PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
|
||||||
{
|
{
|
||||||
BRUSHOBJ *BrushObj;
|
BRUSHOBJ *BrushObj;
|
||||||
XLATEOBJ *RGBtoVGA16;
|
XLATEOBJ *RGBtoVGA16;
|
||||||
|
|
||||||
// FIXME: move color translation routines to W32kSelectObject
|
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
|
||||||
|
BrushObj->iSolidColor = pen->logpen.lopnColor;
|
||||||
|
|
||||||
DbgPrint("PenToBrushObj:%08x ", pen);
|
return BrushObj;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID BitmapToSurf(PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
|
VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
|
||||||
{
|
{
|
||||||
SurfObj->dhsurf = NULL;
|
if(Bitmap->dib)
|
||||||
SurfObj->hsurf = NULL;
|
{
|
||||||
SurfObj->dhpdev = NULL;
|
SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel;
|
||||||
SurfObj->hdev = NULL;
|
SurfObj->lDelta = Bitmap->dib->dsBm.bmWidthBytes;
|
||||||
SurfObj->sizlBitmap = Bitmap->size;
|
SurfObj->pvBits = Bitmap->dib->dsBm.bmBits;
|
||||||
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
|
SurfObj->cjBits = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes;
|
||||||
SurfObj->pvBits = Bitmap->bitmap.bmBits;
|
} else {
|
||||||
SurfObj->pvScan0 = NULL; // start of bitmap
|
SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel;
|
||||||
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
|
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->iUniq = 0; // not sure..
|
||||||
SurfObj->iBitmapFormat = BMF_4BPP; /* FIXME */
|
SurfObj->iBitmapFormat = BitmapFormat(SurfGDI->BitsPerPixel, BI_RGB);
|
||||||
SurfObj->iType = STYPE_BITMAP;
|
SurfObj->iType = STYPE_BITMAP;
|
||||||
SurfObj->fjBitmap = BMF_TOPDOWN;
|
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
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
@ -12,37 +10,37 @@ HPEN
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kCreatePen(INT PenStyle, INT Width, COLORREF Color)
|
W32kCreatePen(INT PenStyle, INT Width, COLORREF Color)
|
||||||
{
|
{
|
||||||
LOGPEN logpen;
|
LOGPEN logpen;
|
||||||
|
|
||||||
logpen.lopnStyle = PenStyle;
|
logpen.lopnStyle = PenStyle;
|
||||||
logpen.lopnWidth.x = Width;
|
logpen.lopnWidth.x = Width;
|
||||||
logpen.lopnWidth.y = 0;
|
logpen.lopnWidth.y = 0;
|
||||||
logpen.lopnColor = Color;
|
logpen.lopnColor = Color;
|
||||||
|
|
||||||
return W32kCreatePenIndirect(&logpen);
|
return W32kCreatePenIndirect(&logpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
HPEN
|
HPEN
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kCreatePenIndirect(CONST PLOGPEN lgpn)
|
W32kCreatePenIndirect(CONST PLOGPEN lgpn)
|
||||||
{
|
{
|
||||||
PPENOBJ penPtr;
|
PPENOBJ penPtr;
|
||||||
HPEN hpen;
|
HPEN hpen;
|
||||||
|
|
||||||
if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
|
if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
|
||||||
|
|
||||||
penPtr = PENOBJ_AllocPen();
|
penPtr = PENOBJ_AllocPen();
|
||||||
hpen = PENOBJ_PtrToHandle(penPtr);
|
hpen = PENOBJ_PtrToHandle(penPtr);
|
||||||
if (!hpen) return 0;
|
if (!hpen) return 0;
|
||||||
PENOBJ_LockPen(hpen);
|
PENOBJ_LockPen(hpen);
|
||||||
|
|
||||||
penPtr->logpen.lopnStyle = lgpn->lopnStyle;
|
penPtr->logpen.lopnStyle = lgpn->lopnStyle;
|
||||||
penPtr->logpen.lopnWidth = lgpn->lopnWidth;
|
penPtr->logpen.lopnWidth = lgpn->lopnWidth;
|
||||||
penPtr->logpen.lopnColor = lgpn->lopnColor;
|
penPtr->logpen.lopnColor = lgpn->lopnColor;
|
||||||
|
|
||||||
PENOBJ_UnlockPen(hpen);
|
PENOBJ_UnlockPen(hpen);
|
||||||
|
|
||||||
return hpen;
|
return hpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
HPEN
|
HPEN
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
|
|
@ -6,10 +6,24 @@
|
||||||
#include <win32k/dc.h>
|
#include <win32k/dc.h>
|
||||||
#include <win32k/text.h>
|
#include <win32k/text.h>
|
||||||
#include <win32k/kapi.h>
|
#include <win32k/kapi.h>
|
||||||
|
#include <freetype/freetype.h>
|
||||||
|
|
||||||
// #define NDEBUG
|
// #define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
|
FT_Library library;
|
||||||
|
|
||||||
|
BOOL InitFontSupport()
|
||||||
|
{
|
||||||
|
ULONG error;
|
||||||
|
|
||||||
|
error = FT_Init_FreeType(&library);
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
} else return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kAddFontResource(LPCWSTR Filename)
|
W32kAddFontResource(LPCWSTR Filename)
|
||||||
|
@ -41,7 +55,7 @@ HFONT
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kCreateFontIndirect(CONST LPLOGFONT lf)
|
W32kCreateFontIndirect(CONST LPLOGFONT lf)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
DbgPrint("WARNING: W32kCreateFontIndirect is current unimplemented\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -336,9 +350,9 @@ W32kSetTextColor(HDC hDC,
|
||||||
PDC dc = DC_HandleToPtr(hDC);
|
PDC dc = DC_HandleToPtr(hDC);
|
||||||
|
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
return 0x80000000;
|
return 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldColor = dc->w.textColor;
|
oldColor = dc->w.textColor;
|
||||||
dc->w.textColor = color;
|
dc->w.textColor = color;
|
||||||
|
@ -364,19 +378,176 @@ W32kTextOut(HDC hDC,
|
||||||
LPCWSTR String,
|
LPCWSTR String,
|
||||||
int Count)
|
int Count)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
||||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
|
||||||
UNICODE_STRING UString;
|
|
||||||
ANSI_STRING AString;
|
|
||||||
|
|
||||||
RtlCreateUnicodeString(&UString, (PWSTR)String);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
|
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
|
// For now we're just going to use an internal font
|
||||||
grWriteCellString(SurfObj, XStart, YStart, AString.Buffer, 0xffffff);
|
// grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
|
||||||
|
|
||||||
RtlFreeAnsiString(&AString);
|
// Prepare the Unicode FileName
|
||||||
RtlFreeUnicodeString(&UString);
|
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
|
UINT
|
||||||
|
@ -387,4 +558,3 @@ W32kTranslateCharsetInfo(PDWORD Src,
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue