Extpen implementation:

- give GDI_OBJECT_TYPE_EXTPEN a sizeof(GDIBRUSHOBJ) and EXTPEN_Cleanup function in GDI_OBJ_INFO table
- define PENOBJ_AllocExtPen, PENOBJ_FreeExtPen, PENOBJ_LockExtPen needed by IntGdiExtCreatePen
- create A Tag for extpen for tagged pool that holds style dwords
- implement IntGdiExtCreatePen
- implement EXTPEN_Cleanup, freeing the stylebuffer
- implement NtGdiExtCreatePen
- make CreateStockObjects, NtGdiCreatePen(Indirect) call IntGdiExtCreatePen
- remove IntGdiCreatePenIndirect

svn path=/trunk/; revision=26619
This commit is contained in:
Timo Kreuzer 2007-05-01 22:04:47 +00:00
parent 5dfe58e2d0
commit 85be5ff46c
8 changed files with 236 additions and 76 deletions

View file

@ -49,8 +49,8 @@ IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color);
/* Pen functions */
HPEN FASTCALL
IntGdiCreatePenIndirect(PLOGPEN lgpn);
HPEN STDCALL
IntGdiExtCreatePen(DWORD, DWORD, IN ULONG, IN ULONG, IN ULONG_PTR, IN ULONG_PTR, DWORD, PULONG, IN ULONG, IN BOOL, IN OPTIONAL HBRUSH);
VOID FASTCALL
IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color);

View file

@ -9,8 +9,12 @@
#define PENOBJ_AllocPen() ((HPEN)GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_PEN))
#define PENOBJ_FreePen(hBMObj) GDIOBJ_FreeObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN)
#define PENOBJ_LockPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_PEN))
#define PENOBJ_AllocExtPen() ((HPEN)GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_EXTPEN))
#define PENOBJ_FreeExtPen(hBMObj) GDIOBJ_FreeObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN)
#define PENOBJ_LockExtPen(hBMObj) ((PGDIBRUSHOBJ)GDIOBJ_LockObj(GdiHandleTable, (HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_EXTPEN))
#define PENOBJ_UnlockPen(pPenObj) GDIOBJ_UnlockObjByPtr(GdiHandleTable, pPenObj)
INT STDCALL PEN_GetObject(PGDIBRUSHOBJ hPen, INT Count, PLOGPEN Buffer);
BOOL INTERNAL_CALL EXTPEN_Cleanup(PVOID ObjectBody);
#endif

View file

@ -43,6 +43,7 @@
#define TAG_PRINT TAG('P', 'R', 'N', 'T') /* print */
#define TAG_REGION TAG('R', 'G', 'N', 'O') /* region */
#define TAG_GDITEXT TAG('T', 'X', 'T', 'O') /* text */
#define TAG_EXTPEN TAG('X', 'P', 'E', 'N') /* extpen */
/* Eng objects */
#define TAG_CLIPOBJ TAG('C', 'L', 'P', 'O') /* clip object */

View file

@ -80,7 +80,7 @@ GDI_OBJ_INFO ObjInfo[] =
{GDI_OBJECT_TYPE_DCE, sizeof(DCE), DCE_Cleanup},
{GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW), DD_Cleanup},
{GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE), DDSURF_Cleanup},
{GDI_OBJECT_TYPE_EXTPEN, 0, GDI_CleanupDummy},
{GDI_OBJECT_TYPE_EXTPEN, sizeof(GDIBRUSHOBJ), EXTPEN_Cleanup},
{GDI_OBJECT_TYPE_METADC, 0, GDI_CleanupDummy},
{GDI_OBJECT_TYPE_METAFILE, 0, GDI_CleanupDummy},
{GDI_OBJECT_TYPE_ENHMETAFILE, 0, GDI_CleanupDummy},

View file

@ -27,19 +27,37 @@
/* PRIVATE FUNCTIONS **********************************************************/
HPEN FASTCALL
IntGdiCreatePenIndirect(PLOGPEN LogPen)
HPEN STDCALL
IntGdiExtCreatePen(
DWORD dwPenStyle,
DWORD dwWidth,
IN ULONG ulBrushStyle,
IN ULONG ulColor,
IN ULONG_PTR ulClientHatch,
IN ULONG_PTR ulHatch,
DWORD dwStyleCount,
PULONG pStyle,
IN ULONG cjDIB,
IN BOOL bOldStylePen,
IN OPTIONAL HBRUSH hbrush)
{
HPEN hPen;
PGDIBRUSHOBJ PenObject;
static const WORD wPatternAlternate[] = {0x5555};
static const WORD wPatternDash[] = {0x0F0F};
static const WORD wPatternDot[] = {0x3333};
static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55};
static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0};
static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38};
static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0};
static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38};
if (LogPen->lopnStyle > PS_INSIDEFRAME)
return 0;
if (bOldStylePen)
{
hPen = PENOBJ_AllocPen();
}
else
{
hPen = PENOBJ_AllocExtPen();
}
hPen = PENOBJ_AllocPen();
if (!hPen)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
@ -47,13 +65,29 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen)
return 0;
}
PenObject = PENOBJ_LockPen(hPen);
if (bOldStylePen)
{
PenObject = PENOBJ_LockPen(hPen);
}
else
{
PenObject = PENOBJ_LockExtPen(hPen);
}
/* FIXME - Handle PenObject == NULL!!! */
PenObject->ptPenWidth = LogPen->lopnWidth;
PenObject->ulPenStyle = LogPen->lopnStyle;
PenObject->BrushAttr.lbColor = LogPen->lopnColor;
PenObject->flAttrs = GDIBRUSH_IS_OLDSTYLEPEN;
switch (LogPen->lopnStyle)
PenObject->ptPenWidth.x = dwWidth;
PenObject->ptPenWidth.y = 0;
PenObject->ulPenStyle = dwPenStyle;
PenObject->BrushAttr.lbColor = ulColor;
PenObject->ulStyle = ulBrushStyle;
// FIXME: copy the bitmap first ?
PenObject->hbmClient = (HANDLE)ulClientHatch;
PenObject->dwStyleCount = dwStyleCount;
PenObject->pStyle = pStyle;
PenObject->flAttrs = bOldStylePen? GDIBRUSH_IS_OLDSTYLEPEN : GDIBRUSH_IS_PEN;
switch (dwPenStyle & PS_STYLE_MASK)
{
case PS_NULL:
PenObject->flAttrs |= GDIBRUSH_IS_NULL;
@ -65,17 +99,27 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen)
case PS_ALTERNATE:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternAlternate);
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
break;
case PS_DOT:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDot);
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
break;
case PS_DASH:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(8, 1, 1, 1, (LPBYTE)wPatternDash);
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
break;
case PS_DASHDOT:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
break;
case PS_DASHDOTDOT:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
break;
case PS_INSIDEFRAME:
@ -83,34 +127,91 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen)
PenObject->flAttrs |= GDIBRUSH_IS_SOLID;
break;
default:
DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED pen %x\n",LogPen->lopnStyle);
}
case PS_USERSTYLE:
/* FIXME: what style here? */
PenObject->flAttrs |= 0;
break;
default:
DPRINT1("IntGdiExtCreatePen unknown penstyle %x\n", dwPenStyle);
}
PENOBJ_UnlockPen(PenObject);
return hPen;
}
INT STDCALL
PEN_GetObject(PGDIBRUSHOBJ PenObject, INT Count, PLOGPEN Buffer)
VOID FASTCALL
IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color)
{
LOGPEN LogPen;
PGDIBRUSHOBJ PenObject;
if( Buffer == NULL ) return sizeof(LOGPEN);
if (Count < sizeof(LOGPEN)) return 0;
if (Count > sizeof(LOGPEN)) Count = sizeof(LOGPEN);
PenObject = PENOBJ_LockPen(hPen);
if (PenObject)
{
if (PenObject->flAttrs & GDIBRUSH_IS_SOLID)
{
PenObject->BrushAttr.lbColor = Color & 0xFFFFFF;
}
PENOBJ_UnlockPen(PenObject);
}
}
if( Buffer == NULL ) return sizeof(LOGPEN);
INT STDCALL
PEN_GetObject(PGDIBRUSHOBJ pPenObject, INT cbCount, PLOGPEN pBuffer)
{
PLOGPEN pLogPen;
PEXTLOGPEN pExtLogPen;
INT cbRetCount;
LogPen.lopnWidth = PenObject->ptPenWidth;
LogPen.lopnStyle = PenObject->ulPenStyle;
LogPen.lopnColor = PenObject->BrushAttr.lbColor;
memcpy(Buffer, &LogPen, Count);
if (pPenObject->flAttrs & GDIBRUSH_IS_OLDSTYLEPEN)
{
cbRetCount = sizeof(LOGPEN);
if (pBuffer)
{
if (cbCount < cbRetCount) return 0;
pLogPen = (PLOGPEN)pBuffer;
pLogPen->lopnWidth = pPenObject->ptPenWidth;
pLogPen->lopnStyle = pPenObject->ulPenStyle;
pLogPen->lopnColor = pPenObject->BrushAttr.lbColor;
}
}
else
{
// FIXME: Can we trust in dwStyleCount being <= 16?
cbRetCount = sizeof(EXTLOGPEN) - sizeof(DWORD) + pPenObject->dwStyleCount * sizeof(DWORD);
if (pBuffer)
{
INT i;
return Count;
if (cbCount < cbRetCount) return 0;
pExtLogPen = (PEXTLOGPEN)pBuffer;
pExtLogPen->elpPenStyle = pPenObject->ulPenStyle;
pExtLogPen->elpWidth = pPenObject->ptPenWidth.x;
pExtLogPen->elpBrushStyle = pPenObject->ulStyle;
pExtLogPen->elpColor = pPenObject->BrushAttr.lbColor;
pExtLogPen->elpHatch = (ULONG_PTR)pPenObject->hbmClient;
pExtLogPen->elpNumEntries = pPenObject->dwStyleCount;
for (i = 0; i < pExtLogPen->elpNumEntries; i++)
{
pExtLogPen->elpStyleEntry[i] = pPenObject->pStyle[i];
}
}
}
return cbRetCount;
}
BOOL INTERNAL_CALL
EXTPEN_Cleanup(PVOID ObjectBody)
{
PGDIBRUSHOBJ pPenObject = (PGDIBRUSHOBJ)ObjectBody;
/* Free the kmode Styles array */
if (pPenObject->pStyle)
{
ExFreePool(pPenObject->pStyle);
}
return TRUE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
@ -122,20 +223,28 @@ NtGdiCreatePen(
COLORREF Color,
IN HBRUSH hbr)
{
LOGPEN LogPen;
if (PenStyle > PS_INSIDEFRAME)
{
PenStyle = PS_SOLID;
}
LogPen.lopnStyle = PenStyle;
LogPen.lopnWidth.x = Width;
LogPen.lopnWidth.y = 0;
LogPen.lopnColor = Color;
return IntGdiCreatePenIndirect(&LogPen);
return IntGdiExtCreatePen(PenStyle,
Width,
BS_SOLID,
Color,
0,
0,
0,
NULL,
0,
TRUE,
0);
}
HPEN STDCALL
NtGdiCreatePenIndirect(CONST PLOGPEN LogPen)
{
LOGPEN SafeLogPen;
LOGPEN SafeLogPen = {0};
NTSTATUS Status = STATUS_SUCCESS;
_SEH_TRY
@ -157,46 +266,89 @@ NtGdiCreatePenIndirect(CONST PLOGPEN LogPen)
return 0;
}
return IntGdiCreatePenIndirect(&SafeLogPen);
return IntGdiExtCreatePen(SafeLogPen.lopnStyle,
SafeLogPen.lopnWidth.x,
BS_SOLID,
SafeLogPen.lopnColor,
0,
0,
0,
NULL,
0,
TRUE,
0);
}
HPEN STDCALL
NtGdiExtCreatePen(
DWORD PenStyle,
DWORD Width,
IN ULONG iBrushStyle,
DWORD dwPenStyle,
DWORD ulWidth,
IN ULONG ulBrushStyle,
IN ULONG ulColor,
IN ULONG_PTR lClientHatch,
IN ULONG_PTR lHatch,
DWORD StyleCount,
PULONG Style,
IN ULONG_PTR ulClientHatch,
IN ULONG_PTR ulHatch,
DWORD dwStyleCount,
PULONG pUnsafeStyle,
IN ULONG cjDIB,
IN BOOL bOldStylePen,
IN OPTIONAL HBRUSH hbrush)
IN OPTIONAL HBRUSH hBrush)
{
LOGPEN LogPen;
NTSTATUS Status = STATUS_SUCCESS;
DWORD* pSafeStyle = NULL;
HPEN hPen;
if (PenStyle & PS_USERSTYLE)
PenStyle = (PenStyle & ~PS_STYLE_MASK) | PS_SOLID;
if (dwStyleCount > 16)
{
return 0;
}
LogPen.lopnStyle = PenStyle & PS_STYLE_MASK;
LogPen.lopnWidth.x = Width;
LogPen.lopnColor = ulColor;
if (dwStyleCount > 0)
{
pSafeStyle = ExAllocatePoolWithTag(NonPagedPool, dwStyleCount * sizeof(DWORD), TAG_EXTPEN);
if (!pSafeStyle)
{
SetLastNtError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
_SEH_TRY
{
ProbeForRead(pUnsafeStyle, dwStyleCount * sizeof(DWORD), 1);
RtlCopyMemory(pSafeStyle,
pUnsafeStyle,
dwStyleCount * sizeof(DWORD));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
ExFreePool(pSafeStyle);
return 0;
}
}
return IntGdiCreatePenIndirect(&LogPen);
hPen = IntGdiExtCreatePen(dwPenStyle,
ulWidth,
ulBrushStyle,
ulColor,
ulClientHatch,
ulHatch,
dwStyleCount,
pSafeStyle,
cjDIB,
bOldStylePen,
hBrush);
if ((!hPen) && (pSafeStyle))
{
ExFreePool(pSafeStyle);
}
return hPen;
}
VOID FASTCALL
IntGdiSetSolidPenColor(HPEN hPen, COLORREF Color)
{
PGDIBRUSHOBJ PenObject;
PenObject = PENOBJ_LockPen(hPen);
if (PenObject->flAttrs & GDIBRUSH_IS_SOLID)
{
PenObject->BrushAttr.lbColor = Color & 0xFFFFFF;
}
PENOBJ_UnlockPen(PenObject);
}
/* EOF */

View file

@ -130,9 +130,9 @@ CreateStockObjects(void)
StockObjects[BLACK_BRUSH] = IntGdiCreateSolidBrush(RGB(0,0,0));
StockObjects[NULL_BRUSH] = IntGdiCreateNullBrush();
StockObjects[WHITE_PEN] = IntGdiCreatePenIndirect(&WhitePen);
StockObjects[BLACK_PEN] = IntGdiCreatePenIndirect(&BlackPen);
StockObjects[NULL_PEN] = IntGdiCreatePenIndirect(&NullPen);
StockObjects[WHITE_PEN] = IntGdiExtCreatePen(WhitePen.lopnStyle, WhitePen.lopnWidth.x, BS_SOLID, WhitePen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL);
StockObjects[BLACK_PEN] = IntGdiExtCreatePen(BlackPen.lopnStyle, BlackPen.lopnWidth.x, BS_SOLID, BlackPen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL);
StockObjects[NULL_PEN] = IntGdiExtCreatePen(NullPen.lopnStyle, NullPen.lopnWidth.x, BS_SOLID, NullPen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL);
(void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]);
@ -296,7 +296,7 @@ CreateSysColorObjects(VOID)
if(SysColorPens[i] == NULL)
{
Pen.lopnColor = SysColors[i];
SysColorPens[i] = IntGdiCreatePenIndirect(&Pen);
SysColorPens[i] = IntGdiExtCreatePen(Pen.lopnStyle, Pen.lopnWidth.x, BS_SOLID, Pen.lopnColor, 0, 0, 0, NULL, 0, TRUE, NULL);
if(SysColorPens[i] != NULL)
{
GDIOBJ_ConvertToStockObj(GdiHandleTable, (HGDIOBJ*)&SysColorPens[i]);

View file

@ -60,6 +60,7 @@ EngUnmapFontFile ( ULONG_PTR iFile )
return EngUnmapFontFileFD ( iFile );
}
#if 0
/*
* @unimplemented
*/
@ -82,6 +83,7 @@ EngTextOut (
UNIMPLEMENTED;
return FALSE;
}
#endif
/*
* @unimplemented

View file

@ -65,6 +65,7 @@
<file>semaphor.c</file>
<file>sort.c</file>
<file>surface.c</file>
<file>engtext.c</file>
<file>transblt.c</file>
<file>engwindow.c</file>
<file>xlate.c</file>