Identation corrected, many fixes and minor improvements, initial DIB support

svn path=/trunk/; revision=1753
This commit is contained in:
Jason Filby 2001-03-31 15:35:08 +00:00
parent a934fd1c24
commit 14c634ca97
42 changed files with 4532 additions and 2967 deletions

View 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);

View 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;
}

View 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;
}

View file

@ -15,32 +15,7 @@
#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 };
@ -52,8 +27,7 @@ BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
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;
@ -61,6 +35,7 @@ BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
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,
@ -72,8 +47,15 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
POINTL ptlTmp; POINTL ptlTmp;
RECT_ENUM RectEnum; RECT_ENUM RectEnum;
BOOL EnumMore; BOOL EnumMore;
SURFGDI *DestGDI, *SourceGDI; PSURFGDI DestGDI, SourceGDI;
HSURF hTemp;
PSURFOBJ TempSurf;
BOOLEAN canCopyBits; BOOLEAN canCopyBits;
POINTL TempPoint;
RECTL TempRect;
SIZEL TempSize;
SourceGDI = AccessInternalObjectFromUserObject(Source);
// If we don't have to do anything special, we can punt to DrvCopyBits // If we don't have to do anything special, we can punt to DrvCopyBits
// if it exists // if it exists
@ -84,65 +66,51 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
} else } else
canCopyBits = FALSE; canCopyBits = FALSE;
// FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
// format. Call DrvDitherColor function where necessary and if available // * The destination bitmap is not managed by the GDI OR
if(Dest->iType != STYPE_BITMAP)
// FIXME: If canCopyBits == TRUE AND the driver has a DrvCopyBits then
// punt to EngCopyBits and not the driver's DrvCopyBits just yet so
// that the EngCopyBits can take care of the clipping drivers
// DrvCopyBits
// FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd
// function to go there instead of the Engine's bltting function
// so as to do the clipping for the driver
// Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
{ {
// Destination surface is device managed // Destination surface is device managed
if(Dest->iType!=STYPE_BITMAP)
{
DestGDI = AccessInternalObjectFromUserObject(Dest); DestGDI = AccessInternalObjectFromUserObject(Dest);
if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
{
return DestGDI->CopyBits(Dest, Source, ClipRegion,
ColorTranslation, DestRect, SourcePoint);
}
if (DestGDI->BitBlt!=NULL) if (DestGDI->BitBlt!=NULL)
{ {
return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion, // The destination is device managed, therefore get the source into a format compatible surface
ColorTranslation, DestRect, SourcePoint, 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;
hTemp = EngCreateBitmap(TempSize,
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
Dest->iBitmapFormat, 0, NULL);
TempSurf = AccessUserObject(hTemp);
// 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->BitBlt(Dest, TempSurf, Mask, ClipRegion,
NULL, DestRect, &TempPoint,
MaskRect, Brush, BrushOrigin, rop4); 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->CopyBits!=NULL) && (canCopyBits == TRUE))
{
return SourceGDI->CopyBits(Dest, Source, ClipRegion,
ColorTranslation, DestRect, SourcePoint);
}
if (SourceGDI->BitBlt!=NULL) if (SourceGDI->BitBlt!=NULL)
{ {
// Request the device driver to return the bitmap in a format compatible with the device
return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion, return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
ColorTranslation, DestRect, SourcePoint, NULL, DestRect, SourcePoint,
MaskRect, Brush, BrushOrigin, rop4); MaskRect, Brush, BrushOrigin, rop4);
// Convert the surface from the driver into the required destination surface
} }
// Should never get here, if it's not GDI managed then the device
// should take care of it
// FIXME: Error message here
}
} }
DestGDI = AccessInternalObjectFromUserObject(Dest); DestGDI = AccessInternalObjectFromUserObject(Dest);
@ -156,43 +124,29 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
clippingType = ClipRegion->iDComplexity; clippingType = ClipRegion->iDComplexity;
} }
// We don't handle color translation just yet // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
if ((rop4 == 0x0000CCCC) &&
((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
{
switch(clippingType) switch(clippingType)
{ {
case DC_TRIVIAL: case DC_TRIVIAL:
BitBltCopy(Dest, Source, CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
DestGDI, SourceGDI,
DestRect, SourcePoint, Source->lDelta);
return(TRUE); return(TRUE);
case DC_RECT: case DC_RECT:
// Clip the blt to the clip rectangle // Clip the blt to the clip rectangle
EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds); EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top; ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
BitBltCopy(Dest, Source,
DestGDI, SourceGDI,
&rclTmp, &ptlTmp, Source->lDelta);
return(TRUE); return(TRUE);
case DC_COMPLEX: case DC_COMPLEX:
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
CD_ANY, ENUM_RECT_LIMIT);
do { do {
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
(PVOID) &RectEnum);
if (RectEnum.c > 0) if (RectEnum.c > 0)
{ {
@ -202,14 +156,8 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
do { do {
EngIntersectRect(prcl, prcl, DestRect); EngIntersectRect(prcl, prcl, DestRect);
ptlTmp.x = SourcePoint->x + prcl->left ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
- DestRect->left; ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
ptlTmp.y = SourcePoint->y + prcl->top
- DestRect->top;
BitBltCopy(Dest, Source,
DestGDI, SourceGDI,
prcl, &ptlTmp, Source->lDelta);
prcl++; prcl++;
@ -220,7 +168,6 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
return(TRUE); return(TRUE);
} }
}
return(FALSE); return(FALSE);
} }

View file

@ -11,63 +11,41 @@
#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;
CurrentSourceCol = SourcePoint->x;
CurrentSourceLine = SourcePoint->y;
// Assign GetPixel DIB function according to bytes per pixel
switch(DestGDI->BitsPerPixel)
{ {
TrivialCopy = 1; case 4:
} else if(ColorTranslation->flXlate & XO_TRIVIAL) return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
{ DestRect, SourcePoint, Delta, ColorTranslation);
TrivialCopy = 1; break;
case 24:
return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
DestRect, SourcePoint, Delta, ColorTranslation);
break;
default:
return FALSE;
} }
leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel; return TRUE;
leftOfDest = DestRect->left * DestGDI->BytesPerPixel;
Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
if(TrivialCopy == 1)
{
for(dy=DestRect->top; dy<DestRect->bottom; dy++)
{
memcpy(DestSurf->pvBits+Delta*dy+leftOfDest,
SourceSurf->pvBits+Delta*dy+leftOfSource,
Width);
}
} else
if(ColorTranslation->flXlate & XO_TABLE)
{
SourceBPP = bytesPerPixel(SourceSurf->iBitmapFormat);
DestBPP = bytesPerPixel(DestSurf->iBitmapFormat);
SourcePos = SourceSurf->pvBits +
(SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP);
SourceInitial = SourcePos;
DestPos = DestSurf->pvBits +
((DestRect->bottom - DestRect->top) * DestSurf->lDelta) + (DestRect->left * DestBPP);
DestInitial = DestPos;
for(i=DestRect->left; i<DestRect->right; i++)
{
memcpy(&RGBulong, SourcePos, SourceBPP);
idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong);
memcpy(DestPos, &idxColor, DestBPP);
SourcePos+=SourceBPP;
DestPos+=DestBPP;
}
SourcePos = SourceInitial + SourceSurf->lDelta;
DestPos = DestInitial + DestSurf->lDelta;
}
} }
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
@ -81,8 +59,6 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
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, // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
// mark the copy block function to be DrvCopyBits instead of the // mark the copy block function to be DrvCopyBits instead of the
// GDI's copy bit function so as to remove clipping from the // GDI's copy bit function so as to remove clipping from the
@ -91,28 +67,25 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
// If one of the surfaces isn't managed by the GDI // If one of the surfaces isn't managed by the GDI
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP)) if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
{ {
// Destination surface is device managed // Destination surface is device managed
if(Dest->iType!=STYPE_BITMAP) if(Dest->iType!=STYPE_BITMAP)
{ {
DestGDI = AccessInternalObjectFromUserObject(Dest); DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
if (DestGDI->CopyBits!=NULL) if (DestGDI->CopyBits!=NULL)
{ {
return DestGDI->CopyBits(Dest, Source, Clip, return DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
ColorTranslation, DestRect, SourcePoint);
} }
} }
// Source surface is device managed // Source surface is device managed
if(Source->iType!=STYPE_BITMAP) if(Source->iType!=STYPE_BITMAP)
{ {
SourceGDI = AccessInternalObjectFromUserObject(Source); SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
if (SourceGDI->CopyBits!=NULL) if (SourceGDI->CopyBits!=NULL)
{ {
return SourceGDI->CopyBits(Dest, Source, Clip, return SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
ColorTranslation, DestRect, SourcePoint);
} }
} }
@ -134,41 +107,32 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
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,
DestRect, SourcePoint, Source->lDelta, ColorTranslation);
return(TRUE); return(TRUE);
case DC_RECT: case DC_RECT:
// Clip the blt to the clip rectangle // Clip the blt to the clip rectangle
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds); EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top; ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
CopyBitsCopy(Dest, Source, CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
DestGDI, SourceGDI,
&rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
return(TRUE); return(TRUE);
case DC_COMPLEX: case DC_COMPLEX:
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
CD_ANY, ENUM_RECT_LIMIT);
do { do {
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
(PVOID) &RectEnum);
if (RectEnum.c > 0) if (RectEnum.c > 0)
{ {
@ -178,14 +142,11 @@ BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
do { do {
EngIntersectRect(prcl, prcl, DestRect); EngIntersectRect(prcl, prcl, DestRect);
ptlTmp.x = SourcePoint->x + prcl->left ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
- DestRect->left; ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
ptlTmp.y = SourcePoint->y + prcl->top
- DestRect->top;
CopyBitsCopy(Dest, Source, if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
DestGDI, SourceGDI, prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
prcl, &ptlTmp, Source->lDelta, ColorTranslation);
prcl++; prcl++;

View file

@ -29,15 +29,8 @@ DWORD STDCALL EngDeviceIoControl(
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);

View file

@ -48,8 +48,7 @@ PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
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;
@ -61,8 +60,7 @@ ULONG AccessHandleFromUserObject(PVOID UserObject)
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;

View file

@ -1,53 +1,53 @@
#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;
// 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;
SurfGDI = AccessInternalObjectFromUserObject(Surface); SurfGDI = AccessInternalObjectFromUserObject(Surface);
if(Surface->iType!=STYPE_BITMAP) if(Surface->iType!=STYPE_BITMAP)
{ {
// Call the driver's DrvLineTo // Call the driver's DrvLineTo
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
RectBounds, mix); }
// 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;
case 24:
DIB_PutPixel = DIB_24BPP_PutPixel;
DIB_HLine = DIB_24BPP_HLine;
DIB_VLine = DIB_24BPP_VLine;
break;
default:
DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
BitsPerFormat(Surface->iBitmapFormat));
return FALSE;
} }
// FIXME: Implement clipping // FIXME: Implement clipping
if(y1==y2) return EngHLine(Surface, SurfGDI, x1, y1, (x2-x1), Brush->iSolidColor);
x=x1; x=x1;
y=y1; y=y1;
deltax=x2-x1; deltax=x2-x1;
@ -57,19 +57,26 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
{ {
xchange=-1; xchange=-1;
deltax=-deltax; deltax=-deltax;
hx = x2;
} else } else
{ {
xchange=1; xchange=1;
hx = x1;
} }
if(deltay<0) if(deltay<0)
{ {
ychange=-1; ychange=-1;
deltay=-deltay; deltay=-deltay;
vy = y2;
} else } else
{ {
ychange=1; 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;
@ -79,7 +86,7 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
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;
@ -95,7 +102,7 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
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)

View file

@ -44,4 +44,3 @@ VOID STDCALL EngFreeUserMem(PVOID pv)
{ {
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */ /* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
} }

View file

@ -88,8 +88,10 @@ typedef VOID (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL);
typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG); typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
typedef BOOL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG);
typedef struct _SURFGDI { typedef struct _SURFGDI {
BYTE BytesPerPixel; INT BitsPerPixel;
PFN_BitBlt BitBlt; PFN_BitBlt BitBlt;
PFN_StretchBlt StretchBlt; PFN_StretchBlt StretchBlt;
@ -103,6 +105,7 @@ typedef struct _SURFGDI {
PFN_Synchronize Synchronize; PFN_Synchronize Synchronize;
BOOL SynchronizeAccess; BOOL SynchronizeAccess;
PFN_CreateDeviceBitmap CreateDeviceBitmap; PFN_CreateDeviceBitmap CreateDeviceBitmap;
PFN_SetPalette SetPalette;
} SURFGDI, *PSURFGDI; } SURFGDI, *PSURFGDI;
typedef struct _XFORMGDI { typedef struct _XFORMGDI {

View file

@ -23,7 +23,7 @@ BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
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;
@ -49,15 +49,11 @@ BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
} 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,
ENUM_RECT_LIMIT);
do { do {
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum); EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
FillSolid(Surface, &RectEnum.arcl[0], iColor); FillSolid(Surface, &RectEnum.arcl[0], iColor);
} while (EnumMore); } while (EnumMore);
} }
@ -84,8 +80,7 @@ BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
} }
// 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)

View file

@ -29,6 +29,12 @@ HPALETTE EngCreatePalette(ULONG Mode,
PalGDI->Mode = Mode; PalGDI->Mode = Mode;
if(Colors != NULL)
{
PalGDI->IndexedColors = ExAllocatePool(NonPagedPool, sizeof(ULONG)*NumColors);
RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(ULONG)*NumColors);
}
if(Mode==PAL_INDEXED) if(Mode==PAL_INDEXED)
{ {
PalGDI->NumColors = NumColors; PalGDI->NumColors = NumColors;

View file

@ -6,43 +6,52 @@
* 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)
{
switch(Compression)
{ {
return 1; case BI_RGB:
} else switch(Bits)
if((Format==BMF_4BPP) || (Format==BMF_4RLE))
{ {
return 1; case 1: return BMF_1BPP;
} else case 4: return BMF_4BPP;
if((Format==BMF_8BPP) || (Format==BMF_8RLE)) case 8: return BMF_8BPP;
{ case 16: return BMF_16BPP;
return 1; case 24: return BMF_24BPP;
} else case 32: return BMF_32BPP;
if(Format==BMF_16BPP)
{
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)
@ -50,6 +59,7 @@ 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)
@ -57,13 +67,11 @@ 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,
@ -76,15 +84,14 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
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->lDelta = ((bytesPerPixel(Format) * Width) + 31) & ~31; // round up 4 bytes
SurfObj->cjBits = SurfObj->lDelta * Size.cy; SurfObj->cjBits = SurfObj->lDelta * Size.cy;
if(Bits!=NULL) if(Bits!=NULL)
@ -129,13 +136,12 @@ HSURF EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
InitializeHooks(SurfGDI); InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format); SurfGDI->BitsPerPixel = BitsPerFormat(Format);
SurfObj->dhsurf = dhsurf; SurfObj->dhsurf = dhsurf;
SurfObj->hsurf = dhsurf; // FIXME: Is this correct?? SurfObj->hsurf = dhsurf; // FIXME: Is this correct??
SurfObj->sizlBitmap = Size; SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format; SurfObj->iBitmapFormat = Format;
SurfObj->lDelta = SurfGDI->BytesPerPixel * Size.cx; SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
SurfObj->iType = STYPE_DEVICE; SurfObj->iType = STYPE_DEVICE;
return NewSurface; return NewSurface;
@ -158,15 +164,10 @@ 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 // Associate the hdev
SurfObj->hdev = Dev; SurfObj->hdev = Dev;
@ -185,6 +186,7 @@ DbgPrint("Associate 1\n");
if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE; if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap; SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
return TRUE; return TRUE;
} }
@ -207,6 +209,5 @@ BOOL EngDeleteSurface(HSURF Surface)
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);
} }

View file

@ -40,6 +40,7 @@ INT abs(INT 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)
{ {
@ -86,8 +87,7 @@ VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
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);
} }
} }
@ -131,6 +131,7 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
((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
@ -141,8 +142,7 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
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
@ -151,8 +151,7 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
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)
{ {
@ -178,14 +177,11 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
// 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;
} }
@ -208,7 +204,6 @@ ULONG *XLATEOBJ_piVector(XLATEOBJ *XlateObj)
{ {
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj); XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(XlateObj->iSrcType == PAL_INDEXED) if(XlateObj->iSrcType == PAL_INDEXED)
{ {
return XlateGDI->translationTable; return XlateGDI->translationTable;
@ -222,6 +217,10 @@ ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
PALGDI *PalGDI; PALGDI *PalGDI;
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj); XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(XlateObj->flXlate & XO_TRIVIAL)
{
return Color;
} else
if(XlateObj->iSrcType == PAL_RGB) if(XlateObj->iSrcType == PAL_RGB)
{ {
// FIXME: should we cache colors used often? // FIXME: should we cache colors used often?
@ -233,7 +232,6 @@ ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
// 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) if(XlateObj->iSrcType == PAL_INDEXED)
{ {
return XlateGDI->translationTable[Color]; return XlateGDI->translationTable[Color];

View file

@ -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,

View file

@ -1,11 +1,10 @@
/* $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)
@ -13,13 +12,9 @@ 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;
} }
@ -34,13 +29,9 @@ EngLoadModule(LPWSTR ModuleName)
// 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;
} }

View file

@ -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
*/ */
@ -26,8 +26,7 @@ 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;
@ -37,11 +36,7 @@ DllMain (
* 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,
NUMBER_OF_SYSCALLS,
Win32kSSPT,
1);
if (Result == FALSE) if (Result == FALSE)
{ {
DbgPrint("Adding system services failed!\n"); DbgPrint("Adding system services failed!\n");
@ -57,13 +52,18 @@ BOOLEAN
STDCALL STDCALL
W32kInitialize (VOID) W32kInitialize (VOID)
{ {
// FIXME: Retrieve name from registry // FIXME: Retrieve name from registry
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys"); EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
// Create surface used to draw the internal font onto // Create surface used to draw the internal font onto
CreateCellCharSurface(); CreateCellCharSurface();
// Create stock objects, ie. precreated objects commonly used by win32 applications
CreateStockObjects();
// Initialize FreeType library
if(!InitFontSupport()) return FALSE;
return TRUE; return TRUE;
} }

View file

@ -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

View file

@ -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,16 +34,12 @@ 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;
@ -53,7 +49,6 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
if (GenericDriver != NULL) if (GenericDriver != NULL)
{ {
ExFreePool(Driver); ExFreePool(Driver);
return FALSE; return FALSE;
} }
@ -78,13 +73,9 @@ PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
} }
/* 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,19 +173,15 @@ 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) + lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) + 10 * sizeof(WCHAR));
10 * sizeof(WCHAR));
wcscpy(lName, L"\\??\\"); wcscpy(lName, L"\\??\\");
if (!wcscmp (Name, L"DISPLAY")) if (!wcscmp (Name, L"DISPLAY"))
{ {

View file

@ -55,52 +55,43 @@
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; dx=Points[3].x-Points[0].x;
dy=Points[3].y-Points[0].y; dy=Points[3].y-Points[0].y;
if(abs(dy)<=abs(dx)){/* shallow line */ if(abs(dy)<=abs(dx)) {/* shallow line */
/* check that control points are between begin and end */ /* check that control points are between begin and end */
if(Points[1].x < Points[0].x){ if(Points[1].x < Points[0].x){
if(Points[1].x < Points[3].x) if(Points[1].x < Points[3].x) return FALSE;
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
if(Points[2].x > Points[3].x)
return FALSE;
dx=BEZIERSHIFTDOWN(dx); dx=BEZIERSHIFTDOWN(dx);
if(!dx) return TRUE; if(!dx) return TRUE;
if(abs(Points[1].y-Points[0].y-(dy/dx)* if(abs(Points[1].y-Points[0].y-(dy/dx)*
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL || BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
abs(Points[2].y-Points[0].y-(dy/dx)* abs(Points[2].y-Points[0].y-(dy/dx)*
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL ) BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL) return FALSE;
return FALSE;
else else
return TRUE; return TRUE;
}else{ /* steep line */ } else{ /* steep line */
/* check that control points are between begin and end */ /* check that control points are between begin and end */
if(Points[1].y < Points[0].y){ if(Points[1].y < Points[0].y){
if(Points[1].y < Points[3].y) if(Points[1].y < Points[3].y) return FALSE;
return FALSE; } else
}else if(Points[1].y > Points[3].y) return FALSE;
if(Points[1].y > Points[3].y)
return FALSE;
if(Points[2].y < Points[0].y){ if(Points[2].y < Points[0].y){
if(Points[2].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[2].y > Points[3].y)
return FALSE;
dy=BEZIERSHIFTDOWN(dy); dy=BEZIERSHIFTDOWN(dy);
if(!dy) return TRUE; if(!dy) return TRUE;
if(abs(Points[1].x-Points[0].x-(dx/dy)* if(abs(Points[1].x-Points[0].x-(dx/dy)*
BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL || BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
abs(Points[2].x-Points[0].x-(dx/dy)* abs(Points[2].x-Points[0].x-(dx/dy)*
BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL ) BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL ) return FALSE;
return FALSE;
else else
return TRUE; return TRUE;
} }

View file

@ -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>
@ -21,13 +20,17 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
{ {
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
// Get the SurfDest
if(DCDest->Surface != NULL)
{
// Use the DC's surface if it has one
SurfDest = AccessUserObject(DCDest->Surface); SurfDest = AccessUserObject(DCDest->Surface);
} else
return FALSE;
DPRINT("Get surfsrc.. ");
// Get the SurfSrc
if(DCSrc->Surface != NULL)
{
DPRINT("from DC's surface\n");
// Use the DC's surface if it has one
SurfSrc = AccessUserObject(DCSrc->Surface); SurfSrc = AccessUserObject(DCSrc->Surface);
SurfGDIDest = AccessInternalObjectFromUserObject(SurfDest);
SurfGDISrc = AccessInternalObjectFromUserObject(SurfSrc);
// Retrieve the logical palette of the destination DC
DCLogPal = AccessUserObject(DCDest->w.hPalette);
if(DCLogPal)
if(DCLogPal->logicalToSystem)
XlateObj = DCLogPal->logicalToSystem;
// If the source and destination formats differ, create an XlateObj [what if we already have one??]
if((BitsPerFormat(SurfDest->iBitmapFormat) != BitsPerFormat(SurfSrc->iBitmapFormat)) && (XlateObj == NULL))
{
if(DCDest->w.hPalette != 0)
{
DestPalette = DCDest->w.hPalette;
} else } else
return FALSE; DestPalette = W32kGetStockObject(DEFAULT_PALETTE);
if(DCSrc->w.hPalette != 0)
{
SourcePalette = DCSrc->w.hPalette;
} else
SourcePalette = W32kGetStockObject(DEFAULT_PALETTE);
DPRINT("Go to EngBitBlt\n"); PalDestGDI = AccessInternalObject(DestPalette);
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL, PalSourceGDI = AccessInternalObject(SourcePalette);
&DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
XlateObj = EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette);
}
// Perform the bitblt operation
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest); if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc); if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
@ -114,8 +129,8 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
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;
@ -132,12 +147,9 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
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,7 +163,7 @@ 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)
{ {
@ -159,8 +171,7 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
} }
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
{ {
@ -171,11 +182,7 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
} }
else else
{ {
hbmpRet = W32kCreateBitmap (Width, hbmpRet = W32kCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
Height,
1,
dc->w.bitsPerPixel,
NULL);
} }
} }
DPRINT ("\t\t%04x\n", hbmpRet); DPRINT ("\t\t%04x\n", hbmpRet);
@ -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)
{ {
@ -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)
@ -430,10 +321,7 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
DPRINT ("Calling device specific BitmapBits\n"); DPRINT ("Calling device specific BitmapBits\n");
if (bmp->DDBitmap->funcs->pBitmapBits) if (bmp->DDBitmap->funcs->pBitmapBits)
{ {
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
(void *) Bits,
Bytes,
DDB_SET);
} }
else else
{ {
@ -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,23 +408,6 @@ 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
@ -634,72 +470,25 @@ HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP 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)
{ {
case 1: words = (width + 31) / 32; break; if(count < sizeof(DIBSECTION))
case 4: words = (width + 7) / 8; break; {
case 8: words = (width + 3) / 4; break; if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
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 */ memcpy(buffer, bmp->dib, count);
return count;
}
else
{ {
colors = info->bmiHeader.biClrUsed; if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
if (!colors && (info->bmiHeader.biBitCount <= 8)) memcpy(buffer, &bmp->bitmap, count);
colors = 1 << info->bmiHeader.biBitCount; return count;
return sizeof(BITMAPINFOHEADER) + colors *
((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
} }
} }

View file

@ -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);
@ -55,24 +56,21 @@ HBRUSH STDCALL W32kCreateDIBPatternBrush(HGLOBAL hDIBPacked,
} }
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, size += DIB_BitmapInfoSize(info, coloruse);
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
} }
@ -107,23 +105,18 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
} }
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);
} }

View file

@ -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;
}

View file

@ -22,18 +22,12 @@ BOOL STDCALL W32kCombineTransform(LPXFORM XFormResult,
} }
/* 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;
@ -134,15 +128,11 @@ 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:

View file

@ -1,4 +1,4 @@
/* $Id: dc.c,v 1.18 2000/07/07 01:20:53 phreak Exp $ /* $Id: dc.c,v 1.19 2001/03/31 15:35:08 jfilby Exp $
* *
* DC.C - Device context functions * DC.C - Device context functions
* *
@ -8,7 +8,6 @@
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
/* FIXME: Surely we should just have one include file that includes all of these.. */
#include <win32k/bitmaps.h> #include <win32k/bitmaps.h>
#include <win32k/coord.h> #include <win32k/coord.h>
#include <win32k/driver.h> #include <win32k/driver.h>
@ -22,83 +21,6 @@
// #define NDEBUG // #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
void TestEngXxx(PDC Dc)
{
BRUSHOBJ brushobj;
HBITMAP GDIbmp;
SURFOBJ *SurfObj, *GDIsurf;
XLATEOBJ *RGBtoVGA16, *VGA16toRGB;
RECTL DestBlt, myrect;
SIZEL GDISize;
CLIPOBJ *clipobj;
POINTL SourcePnt;
INT i;
brushobj.iSolidColor = 1;
SurfObj = AccessUserObject(Dc->Surface);
/* Create a GDI managed bitmap */
GDISize.cx = 100;
GDISize.cy = 100;
GDIbmp = EngCreateBitmap(GDISize, GDISize.cx * 3, BMF_24BPP, BMF_TOPDOWN,
NULL);
// Get GDI surface's object
GDIsurf = AccessUserObject(GDIbmp);
/* Create color translation Xlates */
// Create color translation for RGB to the VGA's 16 colors
RGBtoVGA16 = EngCreateXlate(PAL_INDEXED, PAL_RGB,
Dc->DevInfo.hpalDefault, NULL);
// Create color translation for RGB to the VGA's 16 colors
VGA16toRGB = EngCreateXlate(PAL_RGB, PAL_INDEXED,
NULL, Dc->DevInfo.hpalDefault);
/* Line Tests */
// Diagonals
EngLineTo(SurfObj, NULL, &brushobj, 0, 0, 639, 479, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 639, 0, 0, 479, NULL, NULL);
// Border
EngLineTo(SurfObj, NULL, &brushobj, 0, 0, 639, 0, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 639, 0, 639, 479, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 639, 479, 0, 479, NULL, NULL);
EngLineTo(SurfObj, NULL, &brushobj, 0, 479, 0, 0, NULL, NULL);
/* Paint Tests */
// Colored blocks
for (i=0; i<16; i++)
{
myrect.left=10+i*20;
myrect.top=10;
myrect.right=30+i*20;
myrect.bottom=30;
clipobj = EngCreateClipRegion(1, &myrect, TC_RECTANGLES, NULL);
brushobj.iSolidColor = i;
EngPaint(SurfObj, clipobj, &brushobj, NULL, 0xFF);
EngDeleteClipRegion(clipobj);
}
/* BitBlt */
// Blt VGA to GDI
DestBlt.left=0; DestBlt.top=0; DestBlt.right=100, DestBlt.bottom=100;
SourcePnt.x=10; SourcePnt.y=10;
EngBitBlt(GDIsurf, SurfObj, NULL, NULL, VGA16toRGB, &DestBlt, &SourcePnt,
NULL, NULL, NULL, NULL);
// Blt to VGA again
DestBlt.left=300; DestBlt.top=300; DestBlt.right=400, DestBlt.bottom=400;
SourcePnt.x=0; SourcePnt.y=0;
EngBitBlt(SurfObj, GDIsurf, NULL, NULL, RGBtoVGA16, &DestBlt, &SourcePnt,
NULL, NULL, NULL, NULL);
}
/* FIXME: DCs should probably be thread safe */ /* FIXME: DCs should probably be thread safe */
/* /*
@ -159,10 +81,16 @@ INT STDCALL func_name( HDC hdc, INT mode ) \
// --------------------------------------------------------- File Statics // --------------------------------------------------------- File Statics
static HDC hDISPLAY_DC = NULL; // handle to the DISPLAY HDC
static void W32kSetDCState16(HDC hDC, HDC hDCSave); static void W32kSetDCState16(HDC hDC, HDC hDCSave);
// ----------------------------------------------------- Public Functions // ----------------------------------------------------- Public Functions
HDC RetrieveDisplayHDC()
{
return hDISPLAY_DC;
}
BOOL STDCALL W32kCancelDC(HDC hDC) BOOL STDCALL W32kCancelDC(HDC hDC)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
@ -170,31 +98,37 @@ BOOL STDCALL W32kCancelDC(HDC hDC)
HDC STDCALL W32kCreateCompatableDC(HDC hDC) HDC STDCALL W32kCreateCompatableDC(HDC hDC)
{ {
PDC NewDC, OrigDC; PDC NewDC, OrigDC = NULL;
HBITMAP hBitmap; HBITMAP hBitmap;
if(hDC == NULL)
{
// The OrigDC is one the DC created to reference the DISPLAY (we assume such a DC exists)
if(hDISPLAY_DC != NULL)
OrigDC = DC_HandleToPtr(hDISPLAY_DC);
} else {
OrigDC = DC_HandleToPtr(hDC); OrigDC = DC_HandleToPtr(hDC);
if (OrigDC == NULL) if (OrigDC == NULL)
{ {
return 0; return 0;
} }
}
/* Allocate a new DC based on the original DC's device */ /* Allocate a new DC based on the original DC's device */
NewDC = DC_AllocDC(OrigDC->DriverName); NewDC = DC_AllocDC(OrigDC->DriverName);
if (NewDC == NULL) if (NewDC == NULL)
{ {
DC_UnlockDC(OrigDC); DC_UnlockDC(OrigDC);
return NULL; return NULL;
}
DRIVER_ReferenceDriver (NewDC->DriverName); DRIVER_ReferenceDriver (NewDC->DriverName);
}
/* Copy information from original DC to new DC */ /* Copy information from original DC to new DC */
NewDC->hSelf = NewDC; NewDC->hSelf = NewDC;
/* FIXME: Should this DC request its own PDEV? */ /* FIXME: Should this DC request its own PDEV? */
NewDC->PDev = OrigDC->PDev; NewDC->PDev = OrigDC->PDev;
NewDC->DMW = OrigDC->DMW; NewDC->DMW = OrigDC->DMW;
memcpy(NewDC->FillPatternSurfaces, memcpy(NewDC->FillPatternSurfaces,
OrigDC->FillPatternSurfaces, OrigDC->FillPatternSurfaces,
@ -203,9 +137,9 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
NewDC->DevInfo = OrigDC->DevInfo; NewDC->DevInfo = OrigDC->DevInfo;
/* FIXME: Should this DC request its own surface? */ /* FIXME: Should this DC request its own surface? */
/* Yes, in fact, a 1x1 monochrome surface (to be implemented..) */
NewDC->Surface = OrigDC->Surface; NewDC->Surface = OrigDC->Surface;
NewDC->DriverFunctions = OrigDC->DriverFunctions;
/* DriverName is copied in the AllocDC routine */ /* DriverName is copied in the AllocDC routine */
NewDC->DeviceDriver = OrigDC->DeviceDriver; NewDC->DeviceDriver = OrigDC->DeviceDriver;
NewDC->wndOrgX = OrigDC->wndOrgX; NewDC->wndOrgX = OrigDC->wndOrgX;
@ -228,9 +162,10 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
return NULL; return NULL;
} }
NewDC->w.flags = DC_MEMORY; NewDC->w.flags = DC_MEMORY;
NewDC->w.bitsPerPixel = 1; /* FIXME: OrigDC->w.bitsPerPixel ? */ NewDC->w.bitsPerPixel = 1;
NewDC->w.hBitmap = hBitmap; NewDC->w.hBitmap = hBitmap;
NewDC->w.hFirstBitmap = hBitmap; NewDC->w.hFirstBitmap = hBitmap;
NewDC->w.hPalette = OrigDC->w.hPalette;
DC_UnlockDC(NewDC); DC_UnlockDC(NewDC);
DC_UnlockDC(OrigDC); DC_UnlockDC(OrigDC);
@ -247,7 +182,7 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
PDC NewDC; PDC NewDC;
HDC hDC = NULL; HDC hDC = NULL;
DRVENABLEDATA DED; DRVENABLEDATA DED;
int i; // DELETEME HDC hNewDC;
/* Check for existing DC object */ /* Check for existing DC object */
if ((NewDC = DC_FindOpenDC(Driver)) != NULL) if ((NewDC = DC_FindOpenDC(Driver)) != NULL)
@ -256,7 +191,7 @@ int i; // DELETEME
return W32kCreateCompatableDC(hDC); return W32kCreateCompatableDC(hDC);
} }
DPRINT("NAME: %S\n", Driver); DPRINT("NAME: %S\n", Driver); // FIXME: Should not crash if NULL
/* Allocate a DC object */ /* Allocate a DC object */
if ((NewDC = DC_AllocDC(Driver)) == NULL) if ((NewDC = DC_AllocDC(Driver)) == NULL)
@ -287,7 +222,7 @@ DPRINT("NAME: %S\n", Driver);
DPRINT("DrvEnableDriver failed\n"); DPRINT("DrvEnableDriver failed\n");
goto Failure; goto Failure;
} }
DPRINT("Building DDI Functions\n"); DPRINT("Building DDI Functions\n");
/* Construct DDI driver function dispatch table */ /* Construct DDI driver function dispatch table */
if (!DRIVER_BuildDDIFunctions(&DED, &NewDC->DriverFunctions)) if (!DRIVER_BuildDDIFunctions(&DED, &NewDC->DriverFunctions))
@ -299,7 +234,7 @@ DPRINT("Building DDI Functions\n");
/* Allocate a phyical device handle from the driver */ /* Allocate a phyical device handle from the driver */
if (Device != NULL) if (Device != NULL)
{ {
DPRINT("Device in u: %u\n", Device); DPRINT("Device in u: %u\n", Device);
// wcsncpy(NewDC->DMW.dmDeviceName, Device, DMMAXDEVICENAME); FIXME: this crashes everything? // wcsncpy(NewDC->DMW.dmDeviceName, Device, DMMAXDEVICENAME); FIXME: this crashes everything?
} }
NewDC->DMW.dmSize = sizeof(NewDC->DMW); NewDC->DMW.dmSize = sizeof(NewDC->DMW);
@ -308,15 +243,15 @@ DPRINT("Device in u: %u\n", Device);
/* FIXME: get mode selection information from somewhere */ /* FIXME: get mode selection information from somewhere */
NewDC->DMW.dmLogPixels = 96; NewDC->DMW.dmLogPixels = 96;
NewDC->DMW.dmBitsPerPel = 8; NewDC->DMW.dmBitsPerPel = 4;
NewDC->DMW.dmPelsWidth = 640; NewDC->DMW.dmPelsWidth = 640;
NewDC->DMW.dmPelsHeight = 480; NewDC->DMW.dmPelsHeight = 480;
NewDC->DMW.dmDisplayFlags = 0; NewDC->DMW.dmDisplayFlags = 0;
NewDC->DMW.dmDisplayFrequency = 0; NewDC->DMW.dmDisplayFrequency = 0;
NewDC->w.bitsPerPixel = 8; // FIXME: set this here?? NewDC->w.bitsPerPixel = 4; // FIXME: set this here??
DPRINT("Enabling PDev\n"); DPRINT("Enabling PDev\n");
NewDC->PDev = NewDC->DriverFunctions.EnablePDev(&NewDC->DMW, NewDC->PDev = NewDC->DriverFunctions.EnablePDev(&NewDC->DMW,
L"", L"",
@ -335,29 +270,34 @@ DPRINT("Enabling PDev\n");
goto Failure; goto Failure;
} }
DPRINT("calling completePDev\n"); DPRINT("calling completePDev\n");
/* Complete initialization of the physical device */ /* Complete initialization of the physical device */
NewDC->DriverFunctions.CompletePDev(NewDC->PDev, NewDC); NewDC->DriverFunctions.CompletePDev(NewDC->PDev, NewDC);
DPRINT("calling DRIVER_ReferenceDriver\n"); DPRINT("calling DRIVER_ReferenceDriver\n");
DRIVER_ReferenceDriver (Driver); DRIVER_ReferenceDriver (Driver);
DPRINT("calling EnableSurface\n"); DPRINT("calling EnableSurface\n");
/* Enable the drawing surface */ /* Enable the drawing surface */
NewDC->Surface = NewDC->DriverFunctions.EnableSurface(NewDC->PDev); // hsurf NewDC->Surface = NewDC->DriverFunctions.EnableSurface(NewDC->PDev); // hsurf
NewDC->w.hPalette = NewDC->DevInfo.hpalDefault;
DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel); DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
/* Test EngXxx functions */
// TestEngXxx(NewDC);
/* Initialize the DC state */ /* Initialize the DC state */
DC_InitDC(NewDC); DC_InitDC(NewDC);
hNewDC = DC_PtrToHandle(NewDC);
return DC_PtrToHandle(NewDC); // If we've created a DC for the DISPLAY, save the reference for later CreateCompatibleDC(NULL... usage
if(wcscmp(Driver, "DISPLAY")) // FIXME: this works.. but shouldn't we compare to L"DISPLAY" ? (which doesn't work..)
{
hDISPLAY_DC = hNewDC;
}
return hNewDC;
Failure: Failure:
DC_FreeDC(NewDC); DC_FreeDC(NewDC);
@ -383,7 +323,8 @@ BOOL STDCALL W32kDeleteDC(HDC DCHandle)
return FALSE; return FALSE;
} }
DPRINT( "Deleting DC\n" ); DPRINT( "Deleting DC\n" );
if (!DRIVER_UnreferenceDriver (DCToDelete->DriverName)) if ((!DRIVER_UnreferenceDriver (DCToDelete->DriverName)) &&
(!(DCToDelete->w.flags & DC_MEMORY))) // Don't reset the display if its a memory DC
{ {
DPRINT( "No more references to driver, reseting display\n" ); DPRINT( "No more references to driver, reseting display\n" );
DCToDelete->DriverFunctions.DisableSurface(DCToDelete->PDev); DCToDelete->DriverFunctions.DisableSurface(DCToDelete->PDev);
@ -697,27 +638,155 @@ INT STDCALL W32kGetDeviceCaps(HDC hDC,
DC_GET_VAL( INT, W32kGetMapMode, w.MapMode ) DC_GET_VAL( INT, W32kGetMapMode, w.MapMode )
DC_GET_VAL( INT, W32kGetPolyFillMode, w.polyFillMode ) DC_GET_VAL( INT, W32kGetPolyFillMode, w.polyFillMode )
INT STDCALL W32kGetObject(HGDIOBJ hGDIObj, INT STDCALL W32kGetObjectA(HANDLE handle, INT count, LPVOID buffer)
INT BufSize,
LPVOID Object)
{ {
UNIMPLEMENTED; GDIOBJHDR * ptr;
INT result = 0;
if (!count) return 0;
if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
switch(ptr->wMagic)
{
/* case GO_PEN_MAGIC:
result = PEN_GetObject((PENOBJ *)ptr, count, buffer);
break;
case GO_BRUSH_MAGIC:
result = BRUSH_GetObject((BRUSHOBJ *)ptr, count, buffer);
break; */
case GO_BITMAP_MAGIC:
result = BITMAP_GetObject((BITMAPOBJ *)ptr, count, buffer);
break;
/* case GO_FONT_MAGIC:
result = FONT_GetObjectA((FONTOBJ *)ptr, count, buffer);
// FIXME: Fix the LOGFONT structure for the stock fonts
if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
FixStockFontSizeA(handle, count, buffer);
break;
case GO_PALETTE_MAGIC:
result = PALETTE_GetObject((PALETTEOBJ *)ptr, count, buffer);
break; */
case GO_REGION_MAGIC:
case GO_DC_MAGIC:
case GO_DISABLED_DC_MAGIC:
case GO_META_DC_MAGIC:
case GO_METAFILE_MAGIC:
case GO_METAFILE_DC_MAGIC:
case GO_ENHMETAFILE_MAGIC:
case GO_ENHMETAFILE_DC_MAGIC:
// FIXME("Magic %04x not implemented\n", ptr->wMagic);
break;
default:
DbgPrint("Invalid GDI Magic %04x\n", ptr->wMagic);
break;
}
GDIOBJ_UnlockObject(handle);
return result;
} }
DWORD STDCALL W32kGetObjectType(HGDIOBJ hGDIObj) INT STDCALL W32kGetObjectW(HANDLE handle, INT count, LPVOID buffer)
{ {
UNIMPLEMENTED; GDIOBJHDR * ptr;
INT result = 0;
if (!count) return 0;
if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
switch(ptr->wMagic)
{
/* case GO_PEN_MAGIC:
result = PEN_GetObject((PENOBJ *)ptr, count, buffer);
break;
case GO_BRUSH_MAGIC:
result = BRUSH_GetObject((BRUSHOBJ *)ptr, count, buffer);
break; */
case GO_BITMAP_MAGIC:
result = BITMAP_GetObject((BITMAPOBJ *)ptr, count, buffer);
break;
/* case GO_FONT_MAGIC:
result = FONT_GetObjectW((FONTOBJ *)ptr, count, buffer);
// Fix the LOGFONT structure for the stock fonts
if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
FixStockFontSizeW(handle, count, buffer);
break;
case GO_PALETTE_MAGIC:
result = PALETTE_GetObject((PALETTEOBJ *)ptr, count, buffer);
break; */
default:
// FIXME("Magic %04x not implemented\n", ptr->wMagic);
break;
}
GDIOBJ_UnlockObject(handle);
return result;
}
INT STDCALL W32kGetObject(HANDLE handle, INT count, LPVOID buffer)
{
return W32kGetObjectW(handle, count, buffer);
}
DWORD STDCALL W32kGetObjectType(HANDLE handle)
{
GDIOBJHDR * ptr;
INT result = 0;
if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
switch(ptr->wMagic)
{
case GO_PEN_MAGIC:
result = OBJ_PEN;
break;
case GO_BRUSH_MAGIC:
result = OBJ_BRUSH;
break;
case GO_BITMAP_MAGIC:
result = OBJ_BITMAP;
break;
case GO_FONT_MAGIC:
result = OBJ_FONT;
break;
case GO_PALETTE_MAGIC:
result = OBJ_PAL;
break;
case GO_REGION_MAGIC:
result = OBJ_REGION;
break;
case GO_DC_MAGIC:
result = OBJ_DC;
break;
case GO_META_DC_MAGIC:
result = OBJ_METADC;
break;
case GO_METAFILE_MAGIC:
result = OBJ_METAFILE;
break;
case GO_METAFILE_DC_MAGIC:
result = OBJ_METADC;
break;
case GO_ENHMETAFILE_MAGIC:
result = OBJ_ENHMETAFILE;
break;
case GO_ENHMETAFILE_DC_MAGIC:
result = OBJ_ENHMETADC;
break;
default:
// FIXME("Magic %04x not implemented\n", ptr->wMagic);
break;
}
GDIOBJ_UnlockObject(handle);
return result;
} }
DC_GET_VAL( INT, W32kGetRelAbs, w.relAbsMode ) DC_GET_VAL( INT, W32kGetRelAbs, w.relAbsMode )
DC_GET_VAL( INT, W32kGetROP2, w.ROPmode ) DC_GET_VAL( INT, W32kGetROP2, w.ROPmode )
DC_GET_VAL( INT, W32kGetStretchBltMode, w.stretchBltMode ) DC_GET_VAL( INT, W32kGetStretchBltMode, w.stretchBltMode )
HGDIOBJ STDCALL W32kGetStockObject(INT Object)
{
UNIMPLEMENTED;
}
DC_GET_VAL( UINT, W32kGetTextAlign, w.textAlign ) DC_GET_VAL( UINT, W32kGetTextAlign, w.textAlign )
DC_GET_VAL( COLORREF, W32kGetTextColor, w.textColor ) DC_GET_VAL( COLORREF, W32kGetTextColor, w.textColor )
DC_GET_VAL_EX( W32kGetViewportExtEx, vportExtX, vportExtY, SIZE ) DC_GET_VAL_EX( W32kGetViewportExtEx, vportExtX, vportExtY, SIZE )
@ -749,7 +818,6 @@ BOOL STDCALL W32kRestoreDC(HDC hDC, INT SaveLevel)
if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel)) if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel))
{ {
DC_UnlockDC(hDC); DC_UnlockDC(hDC);
return FALSE; return FALSE;
} }
@ -762,7 +830,6 @@ BOOL STDCALL W32kRestoreDC(HDC hDC, INT SaveLevel)
if (dcs == NULL) if (dcs == NULL)
{ {
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
return FALSE; return FALSE;
} }
GDIOBJ_SetNextObject (hDC, GO_DC_MAGIC, GDIOBJ_GetNextObject (hdcs, GO_DC_MAGIC)); GDIOBJ_SetNextObject (hDC, GO_DC_MAGIC, GDIOBJ_GetNextObject (hdcs, GO_DC_MAGIC));
@ -800,7 +867,6 @@ INT STDCALL W32kSaveDC(HDC hDC)
if (!(hdcs = W32kGetDCState16 (hDC))) if (!(hdcs = W32kGetDCState16 (hDC)))
{ {
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
return 0; return 0;
} }
dcs = DC_HandleToPtr (hdcs); dcs = DC_HandleToPtr (hdcs);
@ -838,6 +904,9 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
PSURFOBJ surfobj; PSURFOBJ surfobj;
PSURFGDI surfgdi; PSURFGDI surfgdi;
PDC dc; PDC dc;
PPENOBJ pen;
PXLATEOBJ XlateObj;
PPALGDI PalGDI;
if(!hDC || !hGDIObj) return NULL; if(!hDC || !hGDIObj) return NULL;
@ -850,6 +919,12 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
case GO_PEN_MAGIC: case GO_PEN_MAGIC:
objOrg = (HGDIOBJ)dc->w.hPen; objOrg = (HGDIOBJ)dc->w.hPen;
dc->w.hPen = hGDIObj; dc->w.hPen = hGDIObj;
// Convert the color of the pen to the format of the DC
PalGDI = AccessInternalObject(dc->w.hPalette);
XlateObj = EngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
pen = GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC);
pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor);
break; break;
case GO_BRUSH_MAGIC: case GO_BRUSH_MAGIC:
objOrg = (HGDIOBJ)dc->w.hBrush; objOrg = (HGDIOBJ)dc->w.hBrush;
@ -861,19 +936,30 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
break; break;
case GO_BITMAP_MAGIC: case GO_BITMAP_MAGIC:
// must be memory dc to select bitmap // must be memory dc to select bitmap
if (!(dc->w.flags & DC_MEMORY)) if (!(dc->w.flags & DC_MEMORY)) return NULL;
return NULL;
objOrg = (HGDIOBJ)dc->w.hBitmap; objOrg = (HGDIOBJ)dc->w.hBitmap;
// setup mem dc for drawing into bitmap // setup mem dc for drawing into bitmap
pb = BITMAPOBJ_HandleToPtr(GdiObjHdr); pb = BITMAPOBJ_HandleToPtr(GdiObjHdr);
surfobj = ExAllocatePool(PagedPool, sizeof(SURFOBJ)); surfobj = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
surfgdi = ExAllocatePool(PagedPool, sizeof(SURFGDI)); surfgdi = ExAllocatePool(PagedPool, sizeof(SURFGDI));
BitmapToSurf(surfgdi, surfobj, pb);
dc->w.hBitmap = (BITMAPOBJ *)GdiObjHdr; BitmapToSurf(hDC, surfgdi, surfobj, pb); // Put the bitmap in a surface
dc->Surface = CreateGDIHandle(surfgdi, surfobj); dc->w.hBitmap = CreateGDIHandle(surfgdi, surfobj); // Assign the DC's bitmap
dc->Surface = dc->w.hBitmap;
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
if(pb->dib)
{
if((pb->dib->dsBmih.biBitCount > 8) && (pb->dib->dsBmih.biBitCount < 24))
{
dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
} else
if(pb->dib->dsBmih.biBitCount >= 24)
{
dc->w.hPalette = EngCreatePalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
}
}
break; break;
#if UPDATEREGIONS #if UPDATEREGIONS
case GO_REGION_MAGIC: case GO_REGION_MAGIC:
@ -926,14 +1012,12 @@ static void W32kSetDCState16(HDC hDC, HDC hDCSave)
if (dcs == NULL) if (dcs == NULL)
{ {
DC_UnlockDC(hDC); DC_UnlockDC(hDC);
return; return;
} }
if (!dcs->w.flags & DC_SAVED) if (!dcs->w.flags & DC_SAVED)
{ {
DC_UnlockDC(hDC); DC_UnlockDC(hDC);
DC_UnlockDC(hDCSave); DC_UnlockDC(hDCSave);
return; return;
} }
@ -1046,8 +1130,7 @@ PDC DC_AllocDC(LPCWSTR Driver)
} }
if (Driver != NULL) if (Driver != NULL)
{ {
NewDC->DriverName = ExAllocatePool(PagedPool, NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR));
(wcslen(Driver) + 1) * sizeof(WCHAR));
wcscpy(NewDC->DriverName, Driver); wcscpy(NewDC->DriverName, Driver);
} }
@ -1056,8 +1139,15 @@ PDC DC_AllocDC(LPCWSTR Driver)
PDC DC_FindOpenDC(LPCWSTR Driver) PDC DC_FindOpenDC(LPCWSTR Driver)
{ {
/* FIXME */ /* FIXME: This is just a hack to return the pointer to the DISPLAY DC.. must cater for others too! */
if(wcscmp(Driver, "DISPLAY"))
{
return DC_HandleToPtr(hDISPLAY_DC);
}
return NULL; return NULL;
} }
void DC_InitDC(PDC DCToInit) void DC_InitDC(PDC DCToInit)
@ -1096,19 +1186,14 @@ DC_UpdateXforms(PDC dc)
xformWnd2Vport.eM12 = 0.0; xformWnd2Vport.eM12 = 0.0;
xformWnd2Vport.eM21 = 0.0; xformWnd2Vport.eM21 = 0.0;
xformWnd2Vport.eM22 = scaleY; xformWnd2Vport.eM22 = scaleY;
xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX - xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX - scaleX * (FLOAT)dc->wndOrgX;
scaleX * (FLOAT)dc->wndOrgX; xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;
xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY -
scaleY * (FLOAT)dc->wndOrgY;
/* Combine with the world transformation */ /* Combine with the world transformation */
W32kCombineTransform(&dc->w.xformWorld2Vport, W32kCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
&dc->w.xformWorld2Wnd,
&xformWnd2Vport );
/* Create inverse of world-to-viewport transformation */ /* Create inverse of world-to-viewport transformation */
dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);
&dc->w.xformVport2World);
} }
BOOL BOOL
@ -1117,8 +1202,7 @@ DC_InvertXform(const XFORM *xformSrc,
{ {
FLOAT determinant; FLOAT determinant;
determinant = xformSrc->eM11*xformSrc->eM22 - determinant = xformSrc->eM11*xformSrc->eM22 - xformSrc->eM12*xformSrc->eM21;
xformSrc->eM12*xformSrc->eM21;
if (determinant > -1e-12 && determinant < 1e-12) if (determinant > -1e-12 && determinant < 1e-12)
{ {
return FALSE; return FALSE;
@ -1128,10 +1212,8 @@ DC_InvertXform(const XFORM *xformSrc,
xformDest->eM12 = -xformSrc->eM12 / determinant; xformDest->eM12 = -xformSrc->eM12 / determinant;
xformDest->eM21 = -xformSrc->eM21 / determinant; xformDest->eM21 = -xformSrc->eM21 / determinant;
xformDest->eM22 = xformSrc->eM11 / determinant; xformDest->eM22 = xformSrc->eM11 / determinant;
xformDest->eDx = -xformSrc->eDx * xformDest->eM11 - xformDest->eDx = -xformSrc->eDx * xformDest->eM11 - xformSrc->eDy * xformDest->eM21;
xformSrc->eDy * xformDest->eM21; xformDest->eDy = -xformSrc->eDx * xformDest->eM12 - xformSrc->eDy * xformDest->eM22;
xformDest->eDy = -xformSrc->eDx * xformDest->eM12 -
xformSrc->eDy * xformDest->eM22;
return TRUE; return TRUE;
} }

View 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);
}

View file

@ -142,5 +142,3 @@ W32kRoundRect(HDC hDC,
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }

View file

@ -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);
@ -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)
@ -116,5 +205,39 @@ HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ 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........
}

View file

@ -112,10 +112,6 @@ W32kLineTo(HDC hDC,
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 {
DbgPrint("W32kLineTo on DC:%08x (h:%08x) with pen handle %08x\n", dc, hDC, dc->w.hPen);
DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
ret = EngLineTo(SurfObj, ret = EngLineTo(SurfObj,
NULL, // ClipObj NULL, // ClipObj
PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)), PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)),

View file

@ -18,39 +18,35 @@ PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
BRUSHOBJ *BrushObj; BRUSHOBJ *BrushObj;
XLATEOBJ *RGBtoVGA16; XLATEOBJ *RGBtoVGA16;
// FIXME: move color translation routines to W32kSelectObject
DbgPrint("PenToBrushObj:%08x ", pen);
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ)); BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
BrushObj->iSolidColor = pen->logpen.lopnColor;
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; return BrushObj;
// CreateGDIHandle(BrushGDI, BrushObj);
} }
VOID BitmapToSurf(PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap) VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
{ {
if(Bitmap->dib)
{
SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel;
SurfObj->lDelta = Bitmap->dib->dsBm.bmWidthBytes;
SurfObj->pvBits = Bitmap->dib->dsBm.bmBits;
SurfObj->cjBits = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes;
} else {
SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel;
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
SurfObj->pvBits = Bitmap->bitmap.bmBits;
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
}
SurfObj->dhsurf = NULL; SurfObj->dhsurf = NULL;
SurfObj->hsurf = NULL; SurfObj->hsurf = NULL;
SurfObj->dhpdev = NULL; SurfObj->dhpdev = NULL;
SurfObj->hdev = NULL; SurfObj->hdev = NULL;
SurfObj->sizlBitmap = Bitmap->size; SurfObj->pvScan0 = SurfObj->pvBits; // start of bitmap
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes; SurfObj->sizlBitmap = Bitmap->size; // FIXME: alloc memory for our own struct?
SurfObj->pvBits = Bitmap->bitmap.bmBits;
SurfObj->pvScan0 = NULL; // start of bitmap
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
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);
} }

View 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;
}

View file

@ -490,8 +490,7 @@ BOOL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
} }
/* Add the Bezier spline to the path */ /* Add the Bezier spline to the path */
PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant, PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant, start);
start);
start=FALSE; start=FALSE;
} while(!end); } while(!end);
@ -704,8 +703,8 @@ static BOOL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed)
if(!pts) return FALSE; if(!pts) return FALSE;
for(i = 1; i < no; i++) for(i = 1; i < no; i++)
PATH_AddEntry(pPath, &pts[i], PATH_AddEntry(pPath, &pts[i], (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO);
(i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO);
ExFreePool(pts); ExFreePool(pts);
return TRUE; return TRUE;
} }
@ -726,12 +725,10 @@ static BOOL PATH_FlattenPath(GdiPath *pPath)
switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) { switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) {
case PT_MOVETO: case PT_MOVETO:
case PT_LINETO: case PT_LINETO:
PATH_AddEntry(&newPath, &pPath->pPoints[srcpt], PATH_AddEntry(&newPath, &pPath->pPoints[srcpt], pPath->pFlags[srcpt]);
pPath->pFlags[srcpt]);
break; break;
case PT_BEZIERTO: case PT_BEZIERTO:
PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt-1], PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt-1], pPath->pFlags[srcpt+2] & PT_CLOSEFIGURE);
pPath->pFlags[srcpt+2] & PT_CLOSEFIGURE);
srcpt += 2; srcpt += 2;
break; break;
} }
@ -883,10 +880,8 @@ static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
{ {
numEntriesToAllocate=pPath->numEntriesAllocated; numEntriesToAllocate=pPath->numEntriesAllocated;
while(numEntriesToAllocate<numEntries) while(numEntriesToAllocate<numEntries)
numEntriesToAllocate=numEntriesToAllocate*GROW_FACTOR_NUMER/ numEntriesToAllocate=numEntriesToAllocate*GROW_FACTOR_NUMER/GROW_FACTOR_DENOM;
GROW_FACTOR_DENOM; } else
}
else
numEntriesToAllocate=numEntries; numEntriesToAllocate=numEntries;
/* Allocate new arrays */ /* Allocate new arrays */
@ -905,10 +900,8 @@ static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
{ {
assert(pPath->pFlags); assert(pPath->pFlags);
memcpy(pPointsNew, pPath->pPoints, memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed);
sizeof(POINT)*pPath->numEntriesUsed); memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
memcpy(pFlagsNew, pPath->pFlags,
sizeof(BYTE)*pPath->numEntriesUsed);
ExFreePool(pPath->pPoints); ExFreePool(pPath->pPoints);
ExFreePool(pPath->pFlags); ExFreePool(pPath->pFlags);
@ -935,8 +928,7 @@ static BOOL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath)
{ {
*ppPath=&pDC->w.path; *ppPath=&pDC->w.path;
return TRUE; return TRUE;
} } else
else
return FALSE; return FALSE;
} }
@ -974,8 +966,7 @@ static BOOL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
yNorm[3]=sin(angleEnd); yNorm[3]=sin(angleEnd);
xNorm[2]=xNorm[3] + a*yNorm[3]; xNorm[2]=xNorm[3] + a*yNorm[3];
yNorm[2]=yNorm[3] - a*xNorm[3]; yNorm[2]=yNorm[3] - a*xNorm[3];
} } else
else
for(i=0; i<4; i++) for(i=0; i<4; i++)
{ {
xNorm[i]=cos(angleStart); xNorm[i]=cos(angleStart);
@ -1011,10 +1002,8 @@ static BOOL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x, static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
double y, POINT *pPoint) double y, POINT *pPoint)
{ {
pPoint->x=GDI_ROUND( (double)corners[0].x + pPoint->x=GDI_ROUND( (double)corners[0].x + (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) );
(double)(corners[1].x-corners[0].x)*0.5*(x+1.0) ); pPoint->y=GDI_ROUND( (double)corners[0].y + (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
pPoint->y=GDI_ROUND( (double)corners[0].y +
(double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
} }
/* PATH_NormalizePoint /* PATH_NormalizePoint
@ -1026,8 +1015,6 @@ static void PATH_NormalizePoint(FLOAT_POINT corners[],
const FLOAT_POINT *pPoint, const FLOAT_POINT *pPoint,
double *pX, double *pY) double *pX, double *pY)
{ {
*pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * 2.0 - 1.0;
2.0 - 1.0; *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) * 2.0 - 1.0;
*pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) *
2.0 - 1.0;
} }

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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
@ -364,19 +378,176 @@ W32kTextOut(HDC hDC,
LPCWSTR String, LPCWSTR String,
int Count) int Count)
{ {
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
SURFOBJ *SurfObj = AccessUserObject(dc->Surface); SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
UNICODE_STRING UString; UNICODE_STRING FileName;
ANSI_STRING AString; int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j;
FT_Face face;
RtlCreateUnicodeString(&UString, (PWSTR)String); FT_GlyphSlot glyph;
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE); 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;
} }