From 7e928974a753954dd5bede9c24f8c548391f1d4c Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 2 Feb 2009 15:01:19 +0000 Subject: [PATCH] (svn r15317) -Fix: support Windows fonts with non-ASCII characters in their file name. Windows doesn't come with them by default, but one can easily install a font with non-ASCII name. --- src/fontcache.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/fontcache.cpp b/src/fontcache.cpp index 96a69db11d..0951f4db6b 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -42,6 +42,37 @@ enum { #include // SHGetFolderPath #include "win32.h" +/** + * Get the short DOS 8.3 format for paths. + * FreeType doesn't support Unicode filenames and Windows' fopen (as used + * by FreeType) doesn't support UTF-8 filenames. So we have to convert the + * filename into something that isn't UTF-8 but represents the Unicode file + * name. This is the short DOS 8.3 format. This does not contain any + * characters that fopen doesn't support. + * @param long_path the path in UTF-8. + * @return the short path in ANSI (ASCII). + */ +char *GetShortPath(const char *long_path) +{ + static char short_path[MAX_PATH]; +#ifdef UNICODE + /* The non-unicode GetShortPath doesn't support UTF-8..., + * so convert the path to wide chars, then get the short + * path and convert it back again. */ + wchar_t long_path_w[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, long_path, -1, long_path_w, MAX_PATH); + + wchar_t short_path_w[MAX_PATH]; + GetShortPathNameW(long_path_w, short_path_w, MAX_PATH); + + WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, MAX_PATH, NULL, NULL); +#else + /* Technically not needed, but do it for consistency. */ + GetShortPathNameA(long_path, short_path, MAX_PATH); +#endif + return short_path; +} + /* Get the font file to be loaded into Freetype by looping the registry * location where windows lists all installed fonts. Not very nice, will * surely break if the registry path changes, but it works. Much better @@ -132,6 +163,10 @@ static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) ttd_strlcat(font_path, "\\", MAX_PATH * sizeof(TCHAR)); ttd_strlcat(font_path, WIDE_TO_MB(dbuffer), MAX_PATH * sizeof(TCHAR)); + + /* Convert the path into something that FreeType understands */ + font_path = GetShortPath(font_path); + index = 0; do { err = FT_New_Face(_library, font_path, index, face);