From: Karsten Blees <bl...@dcon.de>
Date: Sat, 31 Jul 2010 00:04:03 +0000

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 <bl...@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de>
Signed-off-by: Stepan Kasal <ka...@ucw.cz>
---
 compat/winansi.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/compat/winansi.c b/compat/winansi.c
index c4be401..bec6713 100644
--- a/compat/winansi.c
+++ b/compat/winansi.c
@@ -2,8 +2,11 @@
  * Copyright 2008 Peter Harris <g...@peter.is-a-geek.org>
  */
 
+#undef NOGDI
 #include "../git-compat-util.h"
 #include <malloc.h>
+#include <wingdi.h>
+#include <winreg.h>
 
 /*
  Functions to be wrapped:
@@ -27,6 +30,62 @@ static WORD attr;
 static int negative;
 static FILE *last_stream = NULL;
 
+#ifdef __MINGW32__
+typedef struct _CONSOLE_FONT_INFOEX {
+       ULONG cbSize;
+       DWORD nFont;
+       COORD dwFontSize;
+       UINT FontFamily;
+       UINT FontWeight;
+       WCHAR FaceName[LF_FACESIZE];
+} CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX;
+#endif
+
+typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL,
+               PCONSOLE_FONT_INFOEX);
+
+static void print_font_warning(void)
+{
+       warning("Your console font probably doesn\'t support Unicode. If "
+               "you experience strange characters in the output, consider "
+               "switching to a TrueType font such as Lucida Console!");
+}
+
+static void check_truetype_font(void)
+{
+       static int truetype_font_checked;
+       DWORD fontFamily = 0;
+       PGETCURRENTCONSOLEFONTEX pGetCurrentConsoleFontEx;
+
+       /* don't do this twice */
+       if (truetype_font_checked)
+               return;
+       truetype_font_checked = 1;
+
+       /* GetCurrentConsoleFontEx is available since Vista */
+       pGetCurrentConsoleFontEx = (PGETCURRENTCONSOLEFONTEX) GetProcAddress(
+                       GetModuleHandle("kernel32.dll"), 
"GetCurrentConsoleFontEx");
+       if (pGetCurrentConsoleFontEx) {
+               CONSOLE_FONT_INFOEX cfi;
+               cfi.cbSize = sizeof(cfi);
+               if (pGetCurrentConsoleFontEx(console, 0, &cfi))
+                       fontFamily = cfi.FontFamily;
+       } else {
+               /* pre-Vista: check default console font in registry */
+               HKEY hkey;
+               if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CURRENT_USER, 
"Console", 0,
+                               KEY_READ, &hkey)) {
+                       DWORD size = sizeof(fontFamily);
+                       RegQueryValueExA(hkey, "FontFamily", NULL, NULL,
+                                       (LPVOID) &fontFamily, &size);
+                       RegCloseKey(hkey);
+               }
+       }
+
+       if (!(fontFamily & TMPF_TRUETYPE))
+               atexit(print_font_warning);
+}
+
 static int is_console(FILE *stream)
 {
        CONSOLE_SCREEN_BUFFER_INFO sbi;
@@ -69,6 +128,13 @@ static int write_console(const char *str, size_t len)
 
        WriteConsoleW(console, wbuf, wlen, NULL, NULL);
 
+       /*
+        * if non-ascii characters are printed, check that the current console
+        * font supports this
+        */
+       if (wlen != len)
+               check_truetype_font();
+
        /* return original (utf-8 encoded) length */
        return len;
 }
-- 
2.0.0.9635.g0be03cb

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to