Shrink the size of fonts in the 16-bit GDI heap

Jon Griffiths jon_p_griffiths at yahoo.com
Thu Nov 4 20:28:09 CST 2004


Hi,

I have an app that creates an enormous number of fonts, and exhausts
the GDI heap.

from http://www.mytechsupport.ca/support/topic.asp?TOPIC_ID=2938
---
Known Resource "hogs" include:
<snip>
Applications that have the ability to "preview fonts in font list"
such as Office 2000, which load all installed fonts into GDI
resources when the application is launched (requires 1% of GDI
resources per 64 fonts).
---

1% of 64k for 64 fonts = 10 bytes per font. This suggests to me that
our font data should not all be allocated out of the 16-bit heap. The
following patch shrinks the size of each font in the 16-bit heap by
the sizeof a LOGFONTW - 104 bytes. With this applied my app doesn't
overflow the heap. Please try it out and let me know if it causes or
cures any problems.

Cheers,
Jon


=====
"Don't wait for the seas to part, or messiahs to come;
 Don't you sit around and waste this chance..." - Live

jon_p_griffiths at yahoo.com


		
__________________________________ 
Do you Yahoo!? 
Check out the new Yahoo! Front Page. 
www.yahoo.com 
 
-------------- next part --------------
--- wine/dlls/gdi/font.c	2004-09-08 19:32:23.000000000 +0000
+++ wine-develop/dlls/gdi/font.c	2004-11-05 09:10:30.000000000 +0000
@@ -91,7 +91,7 @@
 typedef struct
 {
     GDIOBJHDR   header;
-    LOGFONTW    logfont;
+    LOGFONTW    *logfont;
 } FONTOBJ;
 
 typedef struct
@@ -425,7 +425,9 @@
             WCHAR *pFaceNameItalicSuffix, *pFaceNameBoldSuffix;
             WCHAR* pFaceNameSuffix = NULL;
 
-	    memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
+	    fontPtr->logfont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
+	    /* FIXME: handle failure case */
+	    memcpy( fontPtr->logfont, plf, sizeof(LOGFONTW) );
 
 	    TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s %s => %p\n",
                   plf->lfHeight, plf->lfWidth,
@@ -440,22 +442,22 @@
 
 	    if (plf->lfEscapement != plf->lfOrientation) {
 	      /* this should really depend on whether GM_ADVANCED is set */
-	      fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
+	      fontPtr->logfont->lfOrientation = fontPtr->logfont->lfEscapement;
 	      WARN("orientation angle %f set to "
                    "escapement angle %f for new font %p\n",
                    plf->lfOrientation/10., plf->lfEscapement/10., hFont);
 	    }
 
-            pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
+            pFaceNameItalicSuffix = strstrW(fontPtr->logfont->lfFaceName, ItalicW);
             if (pFaceNameItalicSuffix) {
-                fontPtr->logfont.lfItalic = TRUE;
+                fontPtr->logfont->lfItalic = TRUE;
                 pFaceNameSuffix = pFaceNameItalicSuffix;
             }
 
-            pFaceNameBoldSuffix = strstrW(fontPtr->logfont.lfFaceName, BoldW);
+            pFaceNameBoldSuffix = strstrW(fontPtr->logfont->lfFaceName, BoldW);
             if (pFaceNameBoldSuffix) {
-                if (fontPtr->logfont.lfWeight < FW_BOLD) {
-                    fontPtr->logfont.lfWeight = FW_BOLD;
+                if (fontPtr->logfont->lfWeight < FW_BOLD) {
+                    fontPtr->logfont->lfWeight = FW_BOLD;
                 }
                 if (!pFaceNameSuffix ||
                     (pFaceNameBoldSuffix < pFaceNameSuffix)) {
@@ -589,7 +591,7 @@
     FONTOBJ *font = obj;
     LOGFONT16 lf16;
 
-    FONT_LogFontWTo16( &font->logfont, &lf16 );
+    FONT_LogFontWTo16( font->logfont, &lf16 );
 
     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
     memcpy( buffer, &lf16, count );
@@ -606,7 +608,7 @@
 
     if(!buffer)
         return sizeof(lfA);
-    FONT_LogFontWToA( &font->logfont, &lfA );
+    FONT_LogFontWToA( font->logfont, &lfA );
 
     if (count > sizeof(lfA)) count = sizeof(lfA);
     memcpy( buffer, &lfA, count );
@@ -622,7 +624,7 @@
     if(!buffer)
         return sizeof(LOGFONTW);
     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
-    memcpy( buffer, &font->logfont, count );
+    memcpy( buffer, font->logfont, count );
     return count;
 }
 
@@ -633,6 +635,7 @@
 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
 {
     WineEngDestroyFontInstance( handle );
+    HeapFree(GetProcessHeap(), 0, ((FONTOBJ*)obj)->logfont);
     return GDI_FreeObject( handle, obj );
 }
 
@@ -1028,10 +1031,10 @@
     {
         if (name)
         {
-            lstrcpynW( name, font->logfont.lfFaceName, count );
+            lstrcpynW( name, font->logfont->lfFaceName, count );
             ret = strlenW(name);
         }
-        else ret = strlenW(font->logfont.lfFaceName) + 1;
+        else ret = strlenW(font->logfont->lfFaceName) + 1;
         GDI_ReleaseObj( dc->hFont );
     }
     GDI_ReleaseObj( hdc );


More information about the wine-patches mailing list