Vincent Povirk : gdiplus: Populate the installed font collection.

Alexandre Julliard julliard at winehq.org
Thu May 14 11:07:43 CDT 2009


Module: wine
Branch: master
Commit: ef4d0d970de5d25b2ddaaeb14db32a738b29b64d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ef4d0d970de5d25b2ddaaeb14db32a738b29b64d

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Mon Apr 27 18:56:56 2009 -0500

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..89498bc 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(void)
+{
+    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; i<fonts->count; 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 52a9c39..950e002 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 1ee24a1..af20c75 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(void);
+
 extern BOOL lengthen_path(GpPath *path, INT len);
 
 extern GpStatus trace_path(GpGraphics *graphics, GpPath *path);
@@ -245,6 +247,7 @@ struct GpStringFormat{
 struct GpFontCollection{
     GpFontFamily **FontFamilies;
     INT count;
+    INT allocated;
 };
 
 struct GpFontFamily{




More information about the wine-cvs mailing list