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

View file

@ -319,7 +319,7 @@ DC_vInitDc(
pdc->dcattr.lBreakExtra = 0; pdc->dcattr.lBreakExtra = 0;
pdc->dcattr.cBreak = 0; pdc->dcattr.cBreak = 0;
pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT]; pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT];
// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew); pdc->dclevel.plfnt = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
/* Other stuff */ /* Other stuff */
pdc->hdcNext = NULL; pdc->hdcNext = NULL;
@ -368,6 +368,9 @@ DC_Cleanup(PVOID ObjectBody)
EBRUSHOBJ_vCleanup(&pdc->eboText); EBRUSHOBJ_vCleanup(&pdc->eboText);
EBRUSHOBJ_vCleanup(&pdc->eboBackground); EBRUSHOBJ_vCleanup(&pdc->eboBackground);
/* Release font */
LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
/* Free regions */ /* Free regions */
if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn)) if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn))
GreDeleteObject(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_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal); 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; pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt;
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ /* 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; hOrgFont = pdcattr->hlfntNew;
} }
if (pdc->dclevel.plfnt) LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
if (pNewFnt) GDIOBJ_vReferenceObjectByPointer(&pNewFnt->BaseObject);
pdc->dclevel.plfnt = pNewFnt; pdc->dclevel.plfnt = pNewFnt;
pdc->hlfntCur = hFont; pdc->hlfntCur = hFont;
pdcattr->hlfntNew = hFont; pdcattr->hlfntNew = hFont;

View file

@ -127,6 +127,8 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
/* LFONTOBJ use share and locking. */ /* LFONTOBJ use share and locking. */
pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj); 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->dclevel.plfnt = pNewFnt;
dc->hlfntCur = pgO->hgdiobj; dc->hlfntCur = pgO->hgdiobj;
pdcattr->hlfntNew = pgO->hgdiobj; pdcattr->hlfntNew = pgO->hgdiobj;