Handle references to DC selected fonts, so we don't leak them or use fonts that are already deleted.

svn path=/trunk/; revision=58102
This commit is contained in:
Timo Kreuzer 2013-01-03 08:45:00 +00:00
parent eb2bbd0d4b
commit 1510c13569
5 changed files with 40 additions and 10 deletions

View file

@ -66,7 +66,7 @@ typedef struct _DCLEVEL
POINTL ptlBrushOrigin;
PBRUSH pbrFill;
PBRUSH pbrLine;
PVOID plfnt; /* LFONTOBJ* (TEXTOBJ*) */
_Notnull_ struct _LFONT * plfnt; /* LFONT* (TEXTOBJ*) */
HGDIOBJ hPath; /* HPATH */
FLONG flPath;
LINEATTRS laPath; /* 0x20 bytes */
@ -110,7 +110,7 @@ typedef struct _DC
PVOID hsem; /* PERESOURCE aka HSEMAPHORE */
FLONG flGraphicsCaps;
FLONG flGraphicsCaps2;
PDC_ATTR pdcattr;
_Notnull_ PDC_ATTR pdcattr;
DCLEVEL dclevel;
DC_ATTR dcattr;
HDC hdcNext;
@ -155,18 +155,27 @@ VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
HFONT
NTAPI
DC_hSelectFont(
_In_ PDC pdc,
_In_ HFONT hlfntNew);
HPALETTE
NTAPI
GdiSelectPalette(
HDC hDC,
HPALETTE hpal,
BOOL ForceBackground);
_In_ HDC hDC,
_In_ HPALETTE hpal,
_In_ BOOL ForceBackground);
/* dcutil.c */
COLORREF
FASTCALL
IntGdiSetBkColor (HDC hDC, COLORREF Color);
IntGdiSetBkColor(
_In_ HDC hDC,
_In_ COLORREF Color);
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color);
UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode);
@ -211,14 +220,26 @@ FORCEINLINE
PDC
DC_LockDc(HDC hdc)
{
//if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) return NULL; ???
return GDIOBJ_LockObject(hdc, GDIObjType_DC_TYPE);
PDC pdc;
pdc = GDIOBJ_LockObject(hdc, GDIObjType_DC_TYPE);
if (pdc)
{
ASSERT(GDI_HANDLE_GET_TYPE(pdc->BaseObject.hHmgr) == GDILoObjType_LO_DC_TYPE);
ASSERT(pdc->dclevel.plfnt != NULL);
ASSERT(GDI_HANDLE_GET_TYPE(((POBJ)pdc->dclevel.plfnt)->hHmgr) == GDILoObjType_LO_FONT_TYPE);
}
return pdc;
}
FORCEINLINE
VOID
DC_UnlockDc(PDC pdc)
{
ASSERT(pdc->dclevel.plfnt != NULL);
ASSERT(GDI_HANDLE_GET_TYPE(((POBJ)pdc->dclevel.plfnt)->hHmgr) == GDILoObjType_LO_FONT_TYPE);
GDIOBJ_vUnlockObject(&pdc->BaseObject);
}

View file

@ -319,7 +319,7 @@ DC_vInitDc(
pdc->dcattr.lBreakExtra = 0;
pdc->dcattr.cBreak = 0;
pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT];
// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
pdc->dclevel.plfnt = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
/* Other stuff */
pdc->hdcNext = NULL;
@ -368,6 +368,9 @@ DC_Cleanup(PVOID ObjectBody)
EBRUSHOBJ_vCleanup(&pdc->eboText);
EBRUSHOBJ_vCleanup(&pdc->eboBackground);
/* Release font */
LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
/* Free regions */
if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn))
GreDeleteObject(pdc->rosdc.hClipRgn);

View file

@ -45,7 +45,9 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal);
// FIXME: Handle refs
/* Dereference the old font, reference the new one */
if (pdcDst->dclevel.plfnt) LFONT_ShareUnlockFont(pdcDst->dclevel.plfnt); /// @todo should aways be != NULL
GDIOBJ_vReferenceObjectByPointer(&pdcSrc->dclevel.plfnt->BaseObject);
pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt;
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */

View file

@ -426,6 +426,8 @@ GreSelectFont( HDC hDC, HFONT hFont)
{
hOrgFont = pdcattr->hlfntNew;
}
if (pdc->dclevel.plfnt) LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject);
pdc->dclevel.plfnt = pNewFnt;
pdc->hlfntCur = hFont;
pdcattr->hlfntNew = hFont;

View file

@ -127,6 +127,8 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
/* LFONTOBJ use share and locking. */
pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj);
if (dc->dclevel.plfnt) LFONT_ShareUnlockFont(dc->dclevel.plfnt);
if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject);
dc->dclevel.plfnt = pNewFnt;
dc->hlfntCur = pgO->hgdiobj;
pdcattr->hlfntNew = pgO->hgdiobj;