Fonts getting corrupted in x11drv

Huw Davies h.davies1 at
Thu May 25 04:47:51 CDT 2006

On Thu, May 25, 2006 at 04:49:04PM +1000, Troy Rollo wrote:
> The attached sample program demonstrates a bug in font handling that can lead 
> to corrupted fonts. Compile with "winegcc -g sysfont.c -lgdi32 -lcomdlg32". 
> Run the resulting a.out, and you will see the letter "C" in the top left 
> corner of the window, rendered in the system font. Click anywhere in the 
> client area of the window and the letter will change its shape, even though 
> it is still using the stock SYSTEM_FONT.
> The left click action creates a device context for the default printer and 
> immediately deletes it. As part of the deletion of that device context, 
> DeleteDC selects the stock SYSTEM_FONT into the device context. Since printer 
> device contexts insist on scalable fonts, the existing (bitmapped) GDI font 
> for the system font is unable to serve, so a new one is created, which ends 
> up being based on the Tahoma (TrueType) font. On the next paint loop, when 
> the test program calls SetFont it is the new, scalable font (based on Tahoma) 
> that is found.

Nice catch!  This should fix it.

Huw Davies
huw at

 dlls/gdi/freetype.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c
index 62b55ce..f76138e 100644
--- a/dlls/gdi/freetype.c
+++ b/dlls/gdi/freetype.c
@@ -234,6 +234,7 @@ typedef struct {
     DWORD hash;
     LOGFONTW lf;
     FMAT2 matrix;
+    BOOL can_use_bitmap;
 typedef struct tagHFONTLIST {
@@ -2124,6 +2125,7 @@ static BOOL fontcmp(GdiFont font, FONT_D
     if(font->font_desc.hash != fd->hash) return TRUE;
     if(memcmp(&font->font_desc.matrix, &fd->matrix, sizeof(fd->matrix))) return TRUE;
     if(memcmp(&font->font_desc.lf, &fd->lf, offsetof(LOGFONTW, lfFaceName))) return TRUE;
+    if(!font->font_desc.can_use_bitmap != !fd->can_use_bitmap) return TRUE;
     return strcmpiW(font->font_desc.lf.lfFaceName, fd->lf.lfFaceName);
@@ -2147,6 +2149,7 @@ static void calc_hash(FONT_DESC *pfd)
         hash ^= two_chars;
         if(!*pwc) break;
+    hash ^= !pfd->can_use_bitmap;
     pfd->hash = hash;
@@ -2160,6 +2163,7 @@ static GdiFont find_in_cache(HFONT hfont
     memcpy(&fd.lf, plf, sizeof(LOGFONTW));
     memcpy(&fd.matrix, pxf, sizeof(FMAT2));
+    fd.can_use_bitmap = can_use_bitmap;
     /* try the in-use list */
@@ -2286,6 +2290,7 @@ GdiFont WineEngCreateFontInstance(DC *dc
      memcpy(&ret->font_desc.matrix, &dc->xformWorld2Vport, sizeof(FMAT2));
      memcpy(&ret->font_desc.lf, &lf, sizeof(LOGFONTW));
+     ret->font_desc.can_use_bitmap = can_use_bitmap;
      hflist = HeapAlloc(GetProcessHeap(), 0, sizeof(*hflist));
      hflist->hfont = hfont;

More information about the wine-devel mailing list