From 53586450b4357ed70967702cc5f87f6e40b55211 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 3 Nov 2008 05:38:02 +0000 Subject: [PATCH] - Add new function for locking text font objects when realized. This is for batching support. - Batching works for selected fonts, due to a system initialization bug this is disabled. - Miscellaneous changes and updates. svn path=/trunk/; revision=37159 --- reactos/dll/win32/gdi32/objects/dc.c | 14 ++++-- .../subsystems/win32/win32k/include/text.h | 13 +++-- reactos/subsystems/win32/win32k/objects/dc.c | 4 +- .../subsystems/win32/win32k/objects/font.c | 29 +++++++++-- .../win32/win32k/objects/freetype.c | 49 ++++++++++--------- .../win32/win32k/objects/gdibatch.c | 7 +-- .../subsystems/win32/win32k/objects/text.c | 4 +- 7 files changed, 80 insertions(+), 40 deletions(-) diff --git a/reactos/dll/win32/gdi32/objects/dc.c b/reactos/dll/win32/gdi32/objects/dc.c index bdb6d6b56c1..fbe4d05bf3e 100644 --- a/reactos/dll/win32/gdi32/objects/dc.c +++ b/reactos/dll/win32/gdi32/objects/dc.c @@ -1535,7 +1535,7 @@ SelectObject(HDC hDC, HGDIOBJ hGdiObj) { PDC_ATTR pDc_Attr; -// HGDIOBJ hOldObj = NULL; + HGDIOBJ hOldObj = NULL; // PTEB pTeb; if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) @@ -1580,10 +1580,15 @@ SelectObject(HDC hDC, return NtGdiSelectPen(hDC, hGdiObj); case GDI_OBJECT_TYPE_FONT: + hOldObj = pDc_Attr->hlfntNew; + if (hOldObj == hGdiObj) return hOldObj; #if 0 + pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS; + pDc_Attr->ulDirty_ |= DIRTY_CHARSET; + pDc_Attr->hlfntNew = hGdiObj; pTeb = NtCurrentTeb(); if (((pTeb->GdiTebBatch.HDC == 0) || - (pTeb->GdiTebBatch.HDC == (ULONG)hDC)) && + (pTeb->GdiTebBatch.HDC == hDC)) && ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE) && (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))) { @@ -1594,14 +1599,15 @@ SelectObject(HDC hDC, pgO->hgdiobj = hGdiObj; pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT); - pTeb->GdiTebBatch.HDC = (ULONG)hDC; + pTeb->GdiTebBatch.HDC = hDC; pTeb->GdiBatchCount++; if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); - return pDc_Attr->hlfntNew; + return hOldObj; } #endif // default for select object font return NtGdiSelectFont(hDC, hGdiObj); + #if 0 case GDI_OBJECT_TYPE_METADC: return MFDRV_SelectObject( hDC, hGdiObj); diff --git a/reactos/subsystems/win32/win32k/include/text.h b/reactos/subsystems/win32/win32k/include/text.h index ef2c2114ace..478b9dce1ce 100644 --- a/reactos/subsystems/win32/win32k/include/text.h +++ b/reactos/subsystems/win32/win32k/include/text.h @@ -54,6 +54,8 @@ typedef struct _STRGDI ULONG acFaceNameGlyphs[8]; } STRGDI, *PSTRGDI; +#define TEXTOBJECT_INIT 0x00010000 + /* GDI logical font object */ typedef struct { @@ -62,9 +64,13 @@ typedef struct BASEOBJECT BaseObject; LFTYPE lft; FLONG fl; - ENUMLOGFONTEXDVW logfont; //LOGFONTW logfont; FONTOBJ *Font; - BOOLEAN Initialized; /* Don't reinitialize for each DC */ + WCHAR FullName[LF_FULLFACESIZE]; + WCHAR Style[LF_FACESIZE]; + WCHAR FaceName[LF_FACESIZE]; + DWORD dwOffsetEndArray; +// Fixed: + ENUMLOGFONTEXDVW logfont; } TEXTOBJ, *PTEXTOBJ; /* Internal interface */ @@ -76,7 +82,8 @@ typedef struct #define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_FONT)) #define TEXTOBJ_UnlockText(pBMObj) GDIOBJ_UnlockObjByPtr ((POBJ)pBMObj) -NTSTATUS FASTCALL TextIntRealizeFont(HFONT FontHandle); +PTEXTOBJ FASTCALL RealizeFontInit(HFONT); +NTSTATUS FASTCALL TextIntRealizeFont(HFONT,PTEXTOBJ); NTSTATUS FASTCALL TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont); BOOL FASTCALL InitFontSupport(VOID); BOOL FASTCALL IntIsFontRenderingEnabled(VOID); diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 6309dc8dec1..6a2339ee4a6 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -2216,7 +2216,7 @@ NtGdiSelectFont( if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr; /* FIXME: what if not successful? */ - if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont))) + if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL))) { hOrgFont = pDc_Attr->hlfntNew; pDc_Attr->hlfntNew = hFont; @@ -2668,7 +2668,7 @@ DC_AllocDC(PUNICODE_STRING Driver) Dc_Attr->hpen = NtGdiGetStockObject( BLACK_PEN ); //// Dc_Attr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT); - TextIntRealizeFont(Dc_Attr->hlfntNew); + TextIntRealizeFont(Dc_Attr->hlfntNew,NULL); NewDC->DcLevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE); NewDC->DcLevel.laPath.eMiterLimit = 10.0; diff --git a/reactos/subsystems/win32/win32k/objects/font.c b/reactos/subsystems/win32/win32k/objects/font.c index b7370a44929..fd9c5f6d3e7 100644 --- a/reactos/subsystems/win32/win32k/objects/font.c +++ b/reactos/subsystems/win32/win32k/objects/font.c @@ -55,6 +55,27 @@ FontGetObject(PTEXTOBJ TFont, INT Count, PVOID Buffer) return Count; } +PTEXTOBJ +FASTCALL +RealizeFontInit(HFONT hFont) +{ + NTSTATUS Status = STATUS_SUCCESS; + PTEXTOBJ pTextObj; + + pTextObj = TEXTOBJ_LockText(hFont); + + if ( pTextObj && !pTextObj->fl & TEXTOBJECT_INIT) + { + Status = TextIntRealizeFont(hFont, pTextObj); + if (!NT_SUCCESS(Status)) + { + TEXTOBJ_UnlockText(pTextObj); + return NULL; + } + } + return pTextObj; +} + /** Functions ******************************************************************/ INT @@ -146,7 +167,7 @@ NtGdiGetFontData( if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); DC_UnlockDc(Dc); if (TextObj == NULL) @@ -193,7 +214,7 @@ NtGdiGetFontUnicodeRanges( if(!Dc_Attr) Dc_Attr = &pDc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); if ( TextObj == NULL) { @@ -363,7 +384,7 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC, Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); DC_UnlockDc(dc); if (TextObj == NULL) { @@ -543,7 +564,7 @@ NtGdiHfontCreate( } hNewFont = TextObj->BaseObject.hHmgr; - TextObj->lft = cjElfw; + TextObj->lft = lft; TextObj->fl = fl; RtlCopyMemory (&TextObj->logfont, &SafeLogfont, sizeof(ENUMLOGFONTEXDVW)); diff --git a/reactos/subsystems/win32/win32k/objects/freetype.c b/reactos/subsystems/win32/win32k/objects/freetype.c index ddd0a07ea5f..1ceb5b4ce80 100644 --- a/reactos/subsystems/win32/win32k/objects/freetype.c +++ b/reactos/subsystems/win32/win32k/objects/freetype.c @@ -1488,7 +1488,7 @@ ftGdiGetGlyphOutline( eM11 = xForm.eM11; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); if (!TextObj) { @@ -2249,7 +2249,7 @@ ftGdiGetTextCharsetInfo( Dc_Attr = Dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); if ( TextObj == NULL) { @@ -2465,7 +2465,7 @@ ftGdiGetTextMetricsW( } Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; - TextObj = TEXTOBJ_LockText(Dc_Attr->hlfntNew); + TextObj = RealizeFontInit(Dc_Attr->hlfntNew); if (NULL != TextObj) { FontGDI = ObjToGDI(TextObj->Font, FONT); @@ -2743,7 +2743,7 @@ IntFontType(PFONTGDI Font) NTSTATUS FASTCALL -TextIntRealizeFont(HFONT FontHandle) +TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj) { NTSTATUS Status = STATUS_SUCCESS; PTEXTOBJ TextObj; @@ -2751,21 +2751,26 @@ TextIntRealizeFont(HFONT FontHandle) PW32PROCESS Win32Process; UINT MatchScore; - TextObj = TEXTOBJ_LockText(FontHandle); - if (NULL == TextObj) - { - return STATUS_INVALID_HANDLE; - } + if (!pTextObj) + { + TextObj = TEXTOBJ_LockText(FontHandle); + if (NULL == TextObj) + { + return STATUS_INVALID_HANDLE; + } - if (TextObj->Initialized) - { - TEXTOBJ_UnlockText(TextObj); - return STATUS_SUCCESS; - } + if (TextObj->fl & TEXTOBJECT_INIT) + { + TEXTOBJ_UnlockText(TextObj); + return STATUS_SUCCESS; + } + } + else + TextObj = pTextObj; if (! RtlCreateUnicodeString(&FaceName, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName)) { - TEXTOBJ_UnlockText(TextObj); + if (!pTextObj) TEXTOBJ_UnlockText(TextObj); return STATUS_NO_MEMORY; } SubstituteFontFamily(&FaceName, 0); @@ -2803,12 +2808,12 @@ TextIntRealizeFont(HFONT FontHandle) FontGdi->flRealizedType = 0; FontGdi->Underline = TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfUnderline ? 0xff : 0; FontGdi->StrikeOut = TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfStrikeOut ? 0xff : 0; - TextObj->Initialized = TRUE; + TextObj->fl |= TEXTOBJECT_INIT; Status = STATUS_SUCCESS; } RtlFreeUnicodeString(&FaceName); - TEXTOBJ_UnlockText(TextObj); + if (!pTextObj) TEXTOBJ_UnlockText(TextObj); ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0); @@ -3040,7 +3045,7 @@ ftGdiGetKerningPairs( PFONTGDI Font, } -//////////////// +////////////////// // // Functions needing sorting. // @@ -3343,7 +3348,7 @@ NtGdiExtTextOutW( } } - TextObj = TEXTOBJ_LockText(Dc_Attr->hlfntNew); + TextObj = RealizeFontInit(Dc_Attr->hlfntNew); if(TextObj == NULL) { goto fail; @@ -3796,7 +3801,7 @@ NtGdiGetCharABCWidthsW( Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); DC_UnlockDc(dc); if (TextObj == NULL) @@ -3964,7 +3969,7 @@ NtGdiGetCharWidthW( Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); DC_UnlockDc(dc); if (TextObj == NULL) @@ -4076,7 +4081,7 @@ NtGdiGetGlyphIndicesW( Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; hFont = Dc_Attr->hlfntNew; - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); DC_UnlockDc(dc); if (!TextObj) { diff --git a/reactos/subsystems/win32/win32k/objects/gdibatch.c b/reactos/subsystems/win32/win32k/objects/gdibatch.c index 68c758475ae..fa80c19868e 100644 --- a/reactos/subsystems/win32/win32k/objects/gdibatch.c +++ b/reactos/subsystems/win32/win32k/objects/gdibatch.c @@ -64,6 +64,7 @@ FASTCALL GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) { PDC_ATTR Dc_Attr = NULL; + UserEnterExclusive(); if (dc) { Dc_Attr = dc->pDc_Attr; @@ -95,8 +96,8 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) PGDIBSOBJECT pgO; if(!dc) break; pgO = (PGDIBSOBJECT) pHdr; - if(NT_SUCCESS(TextIntRealizeFont((HFONT) pgO->hgdiobj))) - Dc_Attr->hlfntNew = (HFONT) pgO->hgdiobj; + TextIntRealizeFont((HFONT) pgO->hgdiobj, NULL); + Dc_Attr->ulDirty_ &= ~(DIRTY_CHARSET); } case GdiBCDelObj: case GdiBCDelRgn: @@ -108,7 +109,7 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) default: break; } - + UserLeave(); return pHdr->Size; // Return the full size of the structure. } diff --git a/reactos/subsystems/win32/win32k/objects/text.c b/reactos/subsystems/win32/win32k/objects/text.c index a3e5373198d..7ba2afd701c 100644 --- a/reactos/subsystems/win32/win32k/objects/text.c +++ b/reactos/subsystems/win32/win32k/objects/text.c @@ -209,7 +209,7 @@ NtGdiGetTextExtentExW( } Dc_Attr = dc->pDc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; - TextObj = TEXTOBJ_LockText(Dc_Attr->hlfntNew); + TextObj = RealizeFontInit(Dc_Attr->hlfntNew); if ( TextObj ) { Result = TextIntGetTextExtentPoint(dc, TextObj, String, Count, MaxExtent, @@ -339,7 +339,7 @@ NtGdiGetTextFaceW( hFont = Dc_Attr->hlfntNew; DC_UnlockDc(Dc); - TextObj = TEXTOBJ_LockText(hFont); + TextObj = RealizeFontInit(hFont); ASSERT(TextObj != NULL); Count = min(Count, wcslen(TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName)); Status = MmCopyToCaller(FaceName, TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfFaceName, Count * sizeof(WCHAR));