Skip to content

Commit 1edeb9a

Browse files
kbleesgitster
authored andcommitted
Win32: warn if the console font doesn't support Unicode
Unicode console output won't display correctly with default settings because the default console font ("Terminal") only supports the system's OEM charset. Unfortunately, this is a user specific setting, so it cannot be easily fixed by e.g. some registry tricks in the setup program. This change prints a warning on exit if console output contained non-ascii characters and the console font is supposedly not a TrueType font (which usually have decent Unicode support). Signed-off-by: Karsten Blees <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Stepan Kasal <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 143e615 commit 1edeb9a

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

compat/winansi.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
* Copyright 2008 Peter Harris <[email protected]>
33
*/
44

5+
#undef NOGDI
56
#include "../git-compat-util.h"
67
#include <malloc.h>
8+
#include <wingdi.h>
9+
#include <winreg.h>
710

811
/*
912
Functions to be wrapped:
@@ -27,6 +30,62 @@ static WORD attr;
2730
static int negative;
2831
static FILE *last_stream = NULL;
2932

33+
#ifdef __MINGW32__
34+
typedef struct _CONSOLE_FONT_INFOEX {
35+
ULONG cbSize;
36+
DWORD nFont;
37+
COORD dwFontSize;
38+
UINT FontFamily;
39+
UINT FontWeight;
40+
WCHAR FaceName[LF_FACESIZE];
41+
} CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX;
42+
#endif
43+
44+
typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL,
45+
PCONSOLE_FONT_INFOEX);
46+
47+
static void print_font_warning(void)
48+
{
49+
warning("Your console font probably doesn\'t support Unicode. If "
50+
"you experience strange characters in the output, consider "
51+
"switching to a TrueType font such as Lucida Console!");
52+
}
53+
54+
static void check_truetype_font(void)
55+
{
56+
static int truetype_font_checked;
57+
DWORD fontFamily = 0;
58+
PGETCURRENTCONSOLEFONTEX pGetCurrentConsoleFontEx;
59+
60+
/* don't do this twice */
61+
if (truetype_font_checked)
62+
return;
63+
truetype_font_checked = 1;
64+
65+
/* GetCurrentConsoleFontEx is available since Vista */
66+
pGetCurrentConsoleFontEx = (PGETCURRENTCONSOLEFONTEX) GetProcAddress(
67+
GetModuleHandle("kernel32.dll"), "GetCurrentConsoleFontEx");
68+
if (pGetCurrentConsoleFontEx) {
69+
CONSOLE_FONT_INFOEX cfi;
70+
cfi.cbSize = sizeof(cfi);
71+
if (pGetCurrentConsoleFontEx(console, 0, &cfi))
72+
fontFamily = cfi.FontFamily;
73+
} else {
74+
/* pre-Vista: check default console font in registry */
75+
HKEY hkey;
76+
if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CURRENT_USER, "Console", 0,
77+
KEY_READ, &hkey)) {
78+
DWORD size = sizeof(fontFamily);
79+
RegQueryValueExA(hkey, "FontFamily", NULL, NULL,
80+
(LPVOID) &fontFamily, &size);
81+
RegCloseKey(hkey);
82+
}
83+
}
84+
85+
if (!(fontFamily & TMPF_TRUETYPE))
86+
atexit(print_font_warning);
87+
}
88+
3089
static int is_console(FILE *stream)
3190
{
3291
CONSOLE_SCREEN_BUFFER_INFO sbi;
@@ -69,6 +128,13 @@ static int write_console(const char *str, size_t len)
69128

70129
WriteConsoleW(console, wbuf, wlen, NULL, NULL);
71130

131+
/*
132+
* if non-ascii characters are printed, check that the current console
133+
* font supports this
134+
*/
135+
if (wlen != len)
136+
check_truetype_font();
137+
72138
/* return original (utf-8 encoded) length */
73139
return len;
74140
}

0 commit comments

Comments
 (0)