From e53e9954bb65b8377f31c1bdb187d70389e5c679 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 27 Apr 2009 18:56:56 -0500 Subject: [PATCH] gdiplus: populate the installed font collection --- dlls/gdiplus/font.c | 66 +++++++++++++++++++++++++++++++++++++++- dlls/gdiplus/gdiplus.c | 4 ++ dlls/gdiplus/gdiplus_private.h | 3 ++ 3 files changed, 72 insertions(+), 1 deletions(-) diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index 0b582a7..998602b 100644 --- a/dlls/gdiplus/font.c +++ b/dlls/gdiplus/font.c @@ -844,6 +844,7 @@ GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection** fontCollecti (*fontCollection)->FontFamilies = NULL; (*fontCollection)->count = 0; + (*fontCollection)->allocated = 0; return Ok; } @@ -930,14 +931,77 @@ GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList( return Ok; } +void free_installed_fonts() +{ + while (installedFontCollection.count) + GdipDeleteFontFamily(installedFontCollection.FontFamilies[--installedFontCollection.count]); + HeapFree(GetProcessHeap(), 0, installedFontCollection.FontFamilies); + installedFontCollection.FontFamilies = NULL; + installedFontCollection.allocated = 0; +} + +static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, + DWORD type, LPARAM lParam) +{ + GpFontCollection* fonts = (GpFontCollection*)lParam; + int i; + + /* skip duplicates */ + for (i=0; icount; i++) + if (strcmpiW(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0) + return 1; + + if (fonts->allocated == fonts->count) + { + INT new_alloc_count = fonts->allocated+50; + GpFontFamily** new_family_list = HeapAlloc(GetProcessHeap(), 0, new_alloc_count*sizeof(void*)); + + if (!new_family_list) + return 0; + + memcpy(new_family_list, fonts->FontFamilies, fonts->count*sizeof(void*)); + HeapFree(GetProcessHeap(), 0, fonts->FontFamilies); + fonts->FontFamilies = new_family_list; + fonts->allocated = new_alloc_count; + } + + if (GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &fonts->FontFamilies[fonts->count]) == Ok) + fonts->count++; + else + return 0; + + return 1; +} + GpStatus WINGDIPAPI GdipNewInstalledFontCollection( GpFontCollection** fontCollection) { - FIXME("stub: %p\n",fontCollection); + TRACE("(%p)\n",fontCollection); if (!fontCollection) return InvalidParameter; + if (installedFontCollection.count == 0) + { + HDC hdc; + LOGFONTW lfw; + + hdc = GetDC(0); + + lfw.lfCharSet = DEFAULT_CHARSET; + lfw.lfFaceName[0] = 0; + lfw.lfPitchAndFamily = 0; + + if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)&installedFontCollection, 0)) + { + free_installed_fonts(); + ReleaseDC(0, hdc); + return OutOfMemory; + } + + ReleaseDC(0, hdc); + } + *fontCollection = &installedFontCollection; return Ok; diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c index 35caad8..6561564 100644 --- a/dlls/gdiplus/gdiplus.c +++ b/dlls/gdiplus/gdiplus.c @@ -64,6 +64,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); break; + + case DLL_PROCESS_DETACH: + free_installed_fonts(); + break; } return TRUE; } diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index f3bf797..256a5a8 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -52,6 +52,8 @@ extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1, extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj, REAL tension, REAL *x, REAL *y); +extern void free_installed_fonts(); + extern BOOL lengthen_path(GpPath *path, INT len); extern GpStatus trace_path(GpGraphics *graphics, GpPath *path); @@ -243,6 +245,7 @@ struct GpStringFormat{ struct GpFontCollection{ GpFontFamily **FontFamilies; INT count; + INT allocated; }; struct GpFontFamily{ -- 1.5.4.3