Implement DC_hSelectFont, use it from NtGdiSelectFont and GdiFlushUserBatch. Make sure plfnt is != NULL before dereferencing it in "TEXTOBJ_LockText"

svn path=/trunk/; revision=58109
This commit is contained in:
Timo Kreuzer 2013-01-04 11:02:43 +00:00
parent fd43db5558
commit a65f18771b
4 changed files with 97 additions and 83 deletions

View file

@ -525,6 +525,85 @@ NtGdiSelectClipPath(
return success; return success;
} }
HFONT
NTAPI
DC_hSelectFont(
_In_ PDC pdc,
_In_ HFONT hlfntNew)
{
PLFONT plfntNew;
HFONT hlfntOld;
// Legacy crap that will die with font engine rewrite
if (!NT_SUCCESS(TextIntRealizeFont(hlfntNew, NULL)))
{
return NULL;
}
/* Get the current selected font */
hlfntOld = pdc->dclevel.plfnt->BaseObject.hHmgr;
/* Check if a new font should be selected */
if (hlfntNew != hlfntOld)
{
/* Lock the new font */
plfntNew = LFONT_ShareLockFont(hlfntNew);
if (plfntNew)
{
/* Success, dereference the old font */
LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
/* Select the new font */
pdc->dclevel.plfnt = plfntNew;
pdc->pdcattr->hlfntNew = hlfntNew;
/* Update dirty flags */
pdc->pdcattr->ulDirty_ |= DIRTY_CHARSET;
pdc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
}
else
{
/* Failed, restore old, return NULL */
pdc->pdcattr->hlfntNew = hlfntOld;
hlfntOld = NULL;
}
}
return hlfntOld;
}
HFONT
APIENTRY
NtGdiSelectFont(
_In_ HDC hdc,
_In_ HFONT hfont)
{
HFONT hfontOld;
PDC pdc;
/* Check parameters */
if ((hdc == NULL) || (hfont == NULL))
{
return NULL;
}
/* Lock the DC */
pdc = DC_LockDc(hdc);
if (!pdc)
{
return NULL;
}
/* Call the internal function */
hfontOld = DC_hSelectFont(pdc, hfont);
/* Unlock the DC */
DC_UnlockDc(pdc);
/* Return the previously selected font */
return hfontOld;
}
HANDLE HANDLE
APIENTRY APIENTRY
NtGdiGetDCObject(HDC hDC, INT ObjectType) NtGdiGetDCObject(HDC hDC, INT ObjectType)

View file

@ -395,50 +395,6 @@ RealizeFontInit(HFONT hFont)
return pTextObj; return pTextObj;
} }
HFONT
FASTCALL
GreSelectFont( HDC hDC, HFONT hFont)
{
PDC pdc;
PDC_ATTR pdcattr;
PTEXTOBJ pOrgFnt, pNewFnt = NULL;
HFONT hOrgFont = NULL;
if (!hDC || !hFont) return NULL;
pdc = DC_LockDc(hDC);
if (!pdc)
{
return NULL;
}
if (NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
{
/* LFONTOBJ use share and locking. */
pNewFnt = TEXTOBJ_LockText(hFont);
pdcattr = pdc->pdcattr;
pOrgFnt = pdc->dclevel.plfnt;
if (pOrgFnt)
{
hOrgFont = pOrgFnt->BaseObject.hHmgr;
}
else
{
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;
pdcattr->ulDirty_ |= DIRTY_CHARSET;
pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
}
if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
DC_UnlockDc(pdc);
return hOrgFont;
}
/** Functions ******************************************************************/ /** Functions ******************************************************************/
@ -1122,17 +1078,5 @@ NtGdiHfontCreate(
return hNewFont; return hNewFont;
} }
/*
* @implemented
*/
HFONT
APIENTRY
NtGdiSelectFont(
IN HDC hDC,
IN HFONT hFont)
{
return GreSelectFont(hDC, hFont);
}
/* EOF */ /* EOF */

View file

@ -66,7 +66,6 @@ ULONG
FASTCALL FASTCALL
GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
{ {
BOOL Hit = FALSE;
ULONG Cmd = 0, Size = 0; ULONG Cmd = 0, Size = 0;
PDC_ATTR pdcattr = NULL; PDC_ATTR pdcattr = NULL;
@ -82,27 +81,25 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
Hit = TRUE; DPRINT1("WARNING! GdiBatch Fault!\n");
_SEH2_YIELD(return 0;)
} }
_SEH2_END; _SEH2_END;
if (Hit)
{
DPRINT1("WARNING! GdiBatch Fault!\n");
return 0;
}
// FYI! The thread is approaching the end of sunset.
switch(Cmd) switch(Cmd)
{ {
case GdiBCPatBlt: // Highest pri first! case GdiBCPatBlt:
break; break;
case GdiBCPolyPatBlt: case GdiBCPolyPatBlt:
break; break;
case GdiBCTextOut: case GdiBCTextOut:
break; break;
case GdiBCExtTextOut: case GdiBCExtTextOut:
break; break;
case GdiBCSetBrushOrg: case GdiBCSetBrushOrg:
{ {
PGDIBSSETBRHORG pgSBO; PGDIBSSETBRHORG pgSBO;
@ -112,40 +109,31 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
DC_vSetBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y); DC_vSetBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y);
break; break;
} }
case GdiBCExtSelClipRgn: case GdiBCExtSelClipRgn:
break; break;
case GdiBCSelObj: case GdiBCSelObj:
{ {
PGDIBSOBJECT pgO; PGDIBSOBJECT pgO;
PTEXTOBJ pNewFnt = NULL;
if (!dc) break; if (!dc) break;
pgO = (PGDIBSOBJECT) pHdr; pgO = (PGDIBSOBJECT) pHdr;
if (NT_SUCCESS(TextIntRealizeFont((HFONT)pgO->hgdiobj,NULL))) DC_hSelectFont(dc, (HFONT)pgO->hgdiobj);
{
/* 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;
pdcattr->ulDirty_ |= DIRTY_CHARSET;
pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
}
if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt);
break; break;
} }
case GdiBCDelRgn: case GdiBCDelRgn:
DPRINT("Delete Region Object!\n"); DPRINT("Delete Region Object!\n");
/* Fall through */
case GdiBCDelObj: case GdiBCDelObj:
{ {
PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr; PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr;
GreDeleteObject( pgO->hgdiobj ); GreDeleteObject( pgO->hgdiobj );
break; break;
} }
default: default:
break; break;
} }

View file

@ -85,8 +85,11 @@ FORCEINLINE
TEXTOBJ_LockText(HFONT hfont) TEXTOBJ_LockText(HFONT hfont)
{ {
PLFONT plfnt = LFONT_ShareLockFont(hfont); PLFONT plfnt = LFONT_ShareLockFont(hfont);
KeEnterCriticalRegion(); if (plfnt != 0)
ExAcquirePushLockExclusive(&plfnt->lock); {
KeEnterCriticalRegion();
ExAcquirePushLockExclusive(&plfnt->lock);
}
return plfnt; return plfnt;
} }