Detecting ClearType-optimized fonts
Question:
Is there a way to check if a given font is one of Microsoft's ClearType-optimized fonts?
I guess I could simply hard-code the list of font names, since it's a relatively开发者_如何学C short list, but that seems a bit ugly. Would the font names be the same regardless of Windows' locale and language settings?
Background:
PuTTY looks really ugly with bold, ClearType-enabled, Consolas text. I decided to play around with the source and see if I could figure out the problem, and I think I tracked it down to the following (abbreviated) code:
font_height = cfg.font.height;
if (font_height > 0) {
font_height =
-MulDiv(font_height, GetDeviceCaps(hdc, LOGPIXELSY), 72);
}
}
font_width = 0;
#define f(i,c,w,u) \
fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \
c, OUT_DEFAULT_PRECIS, \
CLIP_DEFAULT_PRECIS, FONT_QUALITY(cfg.font_quality), \
FIXED_PITCH | FF_DONTCARE, cfg.font.name)
f(FONT_NORMAL, cfg.font.charset, fw_dontcare, FALSE);
SelectObject(hdc, fonts[FONT_NORMAL]);
GetTextMetrics(hdc, &tm);
font_height = tm.tmHeight;
font_width = tm.tmAveCharWidth;
f(FONT_BOLD, cfg.font.charset, fw_bold, FALSE);
The intent is to pick a bold font that fits the same dimensions as the normal font. I'm assuming that PuTTY's Consolas text looks ugly because, since Consolas is so heavily optimized to be layed out on specific pixel boundaries, trying to shoehorn it into arbitrary dimensions produces bad results.
So it seems like an appropriate fix would be to detect ClearType-optimized fonts and try and create the bold versions of those fonts using the same width and height as the initial CreateFont call.
I am not sure that I follow quite what is meant by "tracked it down to the following (abbreviated) code", but sure enough Consolas bold looks bad in Putty. Here is putty source of windows/window.c (revision 8914 obtained with subversion "svn co svn://svn.tartarus.org/sgt/putty", on 5 April 2010).
1386 fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \ 1387 c, OUT_DEFAULT_PRECIS, \ 1388 CLIP_DEFAULT_PRECIS, FONT_QUALITY(cfg.font_quality), \ 1389 FIXED_PITCH | FF_DONTCARE, cfg.font.name) 1390 1391 f(FONT_NORMAL, cfg.font.charset, fw_dontcare, FALSE); 1392 1393 SelectObject(hdc, fonts[FONT_NORMAL]); 1394 GetTextMetrics(hdc, &tm); 1395 1396 GetObject(fonts[FONT_NORMAL], sizeof(LOGFONT), &lfont); 1397 1398 if (pick_width == 0 || pick_height == 0) { 1399 font_height = tm.tmHeight; 1400 font_width = tm.tmAveCharWidth; 1401 } ... 1477 if (bold_mode == BOLD_FONT) { 1478 f(FONT_BOLD, cfg.font.charset, fw_bold, FALSE); 1479 }
For 10 pt Consolas, the values of font_height and font_width were -13 and 0 when CreateFont was called for FONT_NORMAL (via the macro f), but 15 and 7 when it was called for FONT_BOLD (the values are changed on lines 1399,1400). Setting the value of width explicitly does not agree well with the Consolas bold font. If window.c is modified so that lines 1477-1479 are moved to come after line 1391 a much nicer bold Consolas font is obtained (I also tried all the other available fonts (Courier, Bitstream, Lucida etc.) and they were not adversely affected. I have sent this suggestion to the Putty team. Here is a figure showing the difference:
ADDED ON JANUARY 16, 2011: The "bug" is still present, and the fix still works. Now the line-numbers in window.c are that lines 1510-1512 should be moved to come after line 1417. Kristjan.
ADDED ON JAN. 13, 2012: The bug is still in version 0.62 of putty (released on Dec. 10, 2011). The linenumbers to move are now 1532-1534 to come after 1439. For completeness here are the steps I carried out in cygwin:
$ svn co svn://svn.tartarus.org/sgt/putty2
$ cd putty
$ perl mkfiles.pl
$ cd windows
$ --- edit window.c and move the 3 lines---
$ make CC=gcc-3 -f Makefile.cyg
$ --- move resulting executable files (including putty.exe) to a suitable folder
$ --- add shortcuts to the executables to Windows start menu
Kristjan
Not sure if this is an answer for you, but making sure the width of the font is an exact integer pixel width, will make fixed width TrueType fonts look good under ClearType.
To achieve this, you will need to 'round' your font height with some trial and error.
精彩评论