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.
--
Huw Davies
huw@codeweavers.com
---
dlls/gdi/freetype.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
e50bddf2d422b99e526979561713474cd489ba90
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;
} FONT_DESC;
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;
return;
}
@@ -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;
calc_hash(&fd);
/* 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;
calc_hash(&ret->font_desc);
hflist = HeapAlloc(GetProcessHeap(), 0, sizeof(*hflist));
hflist->hfont = hfont;