Index: reactos/ntoskrnl/mm/ARM3/pool.c =================================================================== --- reactos/ntoskrnl/mm/ARM3/pool.c (revision 74270) +++ reactos/ntoskrnl/mm/ARM3/pool.c (working copy) @@ -24,7 +24,7 @@ KGUARDED_MUTEX MmPagedPoolMutex; MM_PAGED_POOL_INFO MmPagedPoolInfo; SIZE_T MmAllocatedNonPagedPool; -ULONG MmSpecialPoolTag; +ULONG MmSpecialPoolTag = '*'; ULONG MmConsumedPoolPercentage; BOOLEAN MmProtectFreedNonPagedPool; SLIST_HEADER MiNonPagedPoolSListHead; Index: reactos/win32ss/gdi/eng/engobjects.h =================================================================== --- reactos/win32ss/gdi/eng/engobjects.h (revision 74270) +++ reactos/win32ss/gdi/eng/engobjects.h (working copy) @@ -110,6 +110,8 @@ typedef struct _SHARED_FACE { FT_Face Face; LONG RefCount; + PVOID Buffer; + BOOL IsMemoryFont; } SHARED_FACE, *PSHARED_FACE; typedef struct _FONTGDI { Index: reactos/win32ss/gdi/ntgdi/freetype.c =================================================================== --- reactos/win32ss/gdi/ntgdi/freetype.c (revision 74286) +++ reactos/win32ss/gdi/ntgdi/freetype.c (working copy) @@ -58,40 +58,7 @@ static UNICODE_STRING FontRegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"); -static PSHARED_FACE -SharedFace_Create(FT_Face Face) -{ - PSHARED_FACE Ptr; - Ptr = ExAllocatePoolWithTag(PagedPool, sizeof(SHARED_FACE), TAG_FONT); - if (Ptr) - { - Ptr->Face = Face; - Ptr->RefCount = 1; - } - return Ptr; -} -static void -SharedFace_AddRef(PSHARED_FACE Ptr) -{ - ++Ptr->RefCount; -} - -static void -SharedFace_Release(PSHARED_FACE Ptr) -{ - if (Ptr->RefCount <= 0) - return; - - --Ptr->RefCount; - if (Ptr->RefCount == 0) - { - FT_Done_Face(Ptr->Face); - ExFreePoolWithTag(Ptr, TAG_FONT); - } -} - - /* The FreeType library is not thread safe, so we have to serialize access to it */ static PFAST_MUTEX FreeTypeLock; @@ -189,6 +156,89 @@ /* list head */ static RTL_STATIC_LIST_HEAD(FontSubstListHead); + +static PSHARED_FACE +SharedFace_Create(FT_Face Face, PVOID Buffer, BOOL IsMemoryFont) +{ + PSHARED_FACE Ptr; + Ptr = ExAllocatePoolWithTag(PagedPool, sizeof(SHARED_FACE), TAG_FONT); + if (Ptr) + { + Ptr->Face = Face; + Ptr->RefCount = 1; + Ptr->Buffer = Buffer; + Ptr->IsMemoryFont = IsMemoryFont; + } + return Ptr; +} + +static void +SharedFace_AddRef(PSHARED_FACE Ptr) +{ + ++Ptr->RefCount; +} + +static void RemoveCachedEntry(PFONT_CACHE_ENTRY Entry) +{ + FT_Done_Glyph((FT_Glyph)Entry->BitmapGlyph); + RemoveEntryList(&Entry->ListEntry); + ExFreePoolWithTag(Entry, TAG_FONT); + FontCacheNumEntries--; +} + +static void +RemoveCacheEntries(FT_Face Face) +{ + PLIST_ENTRY CurrentEntry; + PFONT_CACHE_ENTRY FontEntry; + + IntLockFreeType; + + CurrentEntry = FontCacheListHead.Flink; + while (CurrentEntry != &FontCacheListHead) + { + FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry); + + if (FontEntry->Face == Face) + { + PLIST_ENTRY Next = CurrentEntry->Flink; + + RemoveCachedEntry(FontEntry); + + CurrentEntry = Next; + } + else + { + CurrentEntry = CurrentEntry->Flink; + } + } + + IntUnLockFreeType; +} + + +static void +SharedFace_Release(PSHARED_FACE Ptr) +{ + if (Ptr->RefCount <= 0) + return; + + --Ptr->RefCount; + if (Ptr->RefCount == 0) + { + RemoveCacheEntries(Ptr->Face); + FT_Done_Face(Ptr->Face); + if (Ptr->IsMemoryFont) + ExFreePoolWithTag(Ptr->Buffer, TAG_FONT); + else + MmUnmapViewInSystemSpace(Ptr->Buffer); + ExFreePoolWithTag(Ptr, TAG_FONT); + } +} + + + + /* * IntLoadFontSubstList --- loads the list of font substitutes */ @@ -703,7 +753,7 @@ pLoadFont->IsTrueType = TRUE; if (!Error) - SharedFace = SharedFace_Create(Face); + SharedFace = SharedFace_Create(Face, Buffer, pFileName == NULL); if (Error || SharedFace == NULL) { if (Error == FT_Err_Unknown_File_Format) @@ -1110,6 +1160,20 @@ // FIXME: Add RemoveFontResource +static VOID FASTCALL +CleanupFontEntry(PFONT_ENTRY Entry) +{ + PFONTGDI FontGDI = Entry->Font; + PSHARED_FACE SharedFace = FontGDI->SharedFace; + + if (FontGDI->Filename) + ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF); + + EngFreeMem(FontGDI); + SharedFace_Release(SharedFace); + ExFreePoolWithTag(Entry, TAG_FONT); +} + VOID FASTCALL IntGdiCleanupMemEntry(PFONT_ENTRY_MEM Head) { @@ -1121,14 +1185,31 @@ Entry = RemoveHeadList(&Head->ListEntry); FontEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_MEM, ListEntry); - // Delete FontEntry->Entry (FONT_ENTRY*) + CleanupFontEntry(FontEntry->Entry); ExFreePoolWithTag(FontEntry, TAG_FONT); } - // Delete Head->Entry (FONT_ENTRY*) + CleanupFontEntry(Head->Entry); ExFreePoolWithTag(Head, TAG_FONT); } +static VOID FASTCALL +UnlinkFontMemCollection(PFONT_ENTRY_COLL_MEM Collection) +{ + PFONT_ENTRY_MEM Entry = Collection->Entry; + PLIST_ENTRY ListEntry; + RemoveEntryList(&Collection->ListEntry); + + /* Also unlink the FONT_ENTRY stuff from the PrivateFontListHead */ + do { + RemoveEntryList(&Entry->Entry->ListEntry); + + ListEntry = Entry->ListEntry.Flink; + Entry = CONTAINING_RECORD(ListEntry, FONT_ENTRY_MEM, ListEntry); + + } while (Entry != Collection->Entry); +} + BOOL FASTCALL IntGdiRemoveFontMemResource(HANDLE hMMFont) { @@ -1146,7 +1227,7 @@ if (CurrentEntry->Handle == (UINT)hMMFont) { EntryCollection = CurrentEntry; - RemoveEntryList(Entry); + UnlinkFontMemCollection(CurrentEntry); break; } @@ -1164,6 +1245,39 @@ } +VOID FASTCALL +IntGdiCleanupPrivateFontsForProcess() +{ + PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process(); + PLIST_ENTRY Entry; + PFONT_ENTRY_COLL_MEM EntryCollection; + + do + { + EntryCollection = NULL; + + IntLockProcessPrivateFonts(Win32Process); + if (!IsListEmpty(&Win32Process->PrivateMemFontListHead)) + { + Entry = Win32Process->PrivateMemFontListHead.Flink; + EntryCollection = CONTAINING_RECORD(Entry, FONT_ENTRY_COLL_MEM, ListEntry); + UnlinkFontMemCollection(EntryCollection); + } + IntUnLockProcessPrivateFonts(Win32Process); + + if (EntryCollection) + { + IntGdiCleanupMemEntry(EntryCollection->Entry); + ExFreePoolWithTag(EntryCollection, TAG_FONT); + } + + + + + } while (EntryCollection); + +} + BOOL FASTCALL IntIsFontRenderingEnabled(VOID) { @@ -1737,7 +1851,7 @@ Entry = Head->Flink; while (Entry != Head) { - CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); + CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); FontGDI = CurrentEntry->Font; ASSERT(FontGDI); @@ -1774,7 +1888,8 @@ PPROCESSINFO Win32Process; PFONTGDI Font; - /* Search the process local list */ + /* Search the process local list. + We do not have to search the 'Mem' list, since those fonts are linked in the PrivateFontListHead */ Win32Process = PsGetCurrentProcessWin32Process(); IntLockProcessPrivateFonts(Win32Process); Font = FindFaceNameInList(FaceName, &Win32Process->PrivateFontListHead); @@ -2336,7 +2451,7 @@ CurrentEntry = FontCacheListHead.Flink; while (CurrentEntry != &FontCacheListHead) { - FontEntry = (PFONT_CACHE_ENTRY)CurrentEntry; + FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry); if ((FontEntry->Face == Face) && (FontEntry->GlyphIndex == GlyphIndex) && (FontEntry->Height == Height) && @@ -2457,11 +2572,8 @@ InsertHeadList(&FontCacheListHead, &NewEntry->ListEntry); if (FontCacheNumEntries++ > MAX_FONT_CACHE) { - NewEntry = (PFONT_CACHE_ENTRY)FontCacheListHead.Blink; - FT_Done_Glyph((FT_Glyph)NewEntry->BitmapGlyph); - RemoveTailList(&FontCacheListHead); - ExFreePoolWithTag(NewEntry, TAG_FONT); - FontCacheNumEntries--; + NewEntry = CONTAINING_RECORD(FontCacheListHead.Blink, FONT_CACHE_ENTRY, ListEntry); + RemoveCachedEntry(NewEntry); } return BitmapGlyph; @@ -4116,7 +4228,7 @@ Entry = Head->Flink; while (Entry != Head) { - CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); + CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); FontGDI = CurrentEntry->Font; ASSERT(FontGDI); Face = FontGDI->SharedFace->Face; Index: reactos/win32ss/gdi/ntgdi/init.c =================================================================== --- reactos/win32ss/gdi/ntgdi/init.c (revision 74285) +++ reactos/win32ss/gdi/ntgdi/init.c (working copy) @@ -50,6 +50,8 @@ ASSERT(ppiCurrent); ASSERT(ppiCurrent->peProcess == Process); + IntGdiCleanupPrivateFontsForProcess(); + /* And GDI ones too */ GDI_CleanupForProcess(Process); Index: reactos/win32ss/gdi/ntgdi/text.h =================================================================== --- reactos/win32ss/gdi/ntgdi/text.h (revision 74285) +++ reactos/win32ss/gdi/ntgdi/text.h (working copy) @@ -112,6 +112,7 @@ VOID FASTCALL IntEnableFontRendering(BOOL Enable); ULONG FASTCALL FontGetObject(PTEXTOBJ TextObj, ULONG Count, PVOID Buffer); VOID FASTCALL IntLoadSystemFonts(VOID); +VOID FASTCALL IntGdiCleanupPrivateFontsForProcess(); INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics); HANDLE FASTCALL IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded); BOOL FASTCALL IntGdiRemoveFontMemResource(HANDLE hMMFont);