static HMODULE WINAPI OVRLoadLibraryW( __in LPCWSTR lpLibFileName ) { WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr OVRTargetAPI targetAPI = DirectX; bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); if( !needShim ) return (*oldProcW)( lpLibFileName ); return createShim( lpLibFileName_cstr, targetAPI ); }
static HMODULE WINAPI OVRLoadLibraryExW( __in LPCWSTR lpLibFileName, __reserved HANDLE hFile, __in DWORD dwFlags ) { WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr OVRTargetAPI targetAPI = DirectX; bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); if( !needShim ) return (*oldProcExW)( lpLibFileName, hFile, dwFlags ); // FIXME: Don't throw away the flags parameter return createShim( lpLibFileName_cstr, targetAPI ); }
static BOOL WINAPI OVRGetModuleHandleExW( __in DWORD dwFlags, __in_opt LPCWSTR lpModuleName, __out HMODULE *phModule ) { WIDE_TO_MB(lpModuleName); // Convert lpModuleName -> lpModuleName_cstr OVRTargetAPI targetAPI = DirectX; bool needShim = checkForOverride( lpModuleName_cstr, targetAPI ); if( !needShim ) { return (*oldProcModExW)( dwFlags, lpModuleName, phModule ); } *phModule = createShim( lpModuleName_cstr, targetAPI ); return TRUE; }
static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam) { EFCParam *info = (EFCParam *)lParam; /* Only use TrueType fonts */ if (!(type & TRUETYPE_FONTTYPE)) return 1; /* Don't use SYMBOL fonts */ if (logfont->elfLogFont.lfCharSet == SYMBOL_CHARSET) return 1; /* The font has to have at least one of the supported locales to be usable. */ if ((metric->ntmFontSig.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (metric->ntmFontSig.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) { /* On win9x metric->ntmFontSig seems to contain garbage. */ FONTSIGNATURE fs; memset(&fs, 0, sizeof(fs)); HFONT font = CreateFontIndirect(&logfont->elfLogFont); if (font != NULL) { HDC dc = GetDC(NULL); HGDIOBJ oldfont = SelectObject(dc, font); GetTextCharsetInfo(dc, &fs, 0); SelectObject(dc, oldfont); ReleaseDC(NULL, dc); DeleteObject(font); } if ((fs.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (fs.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) return 1; } const char *english_name = GetEnglishFontName(logfont); const char *font_name = WIDE_TO_MB((const TCHAR*)logfont->elfFullName); DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name); strecpy(info->settings->small_font, font_name, lastof(info->settings->small_font)); strecpy(info->settings->medium_font, font_name, lastof(info->settings->medium_font)); strecpy(info->settings->large_font, font_name, lastof(info->settings->large_font)); /* Add english name after font name */ strecpy(info->settings->small_font + strlen(info->settings->small_font) + 1, english_name, lastof(info->settings->small_font)); strecpy(info->settings->medium_font + strlen(info->settings->medium_font) + 1, english_name, lastof(info->settings->medium_font)); strecpy(info->settings->large_font + strlen(info->settings->large_font) + 1, english_name, lastof(info->settings->large_font)); return 0; // stop enumerating }
/** * Fonts can have localised names and when the system locale is the same as * one of those localised names Windows will always return that localised name * instead of allowing to get the non-localised (English US) name of the font. * This will later on give problems as freetype uses the non-localised name of * the font and we need to compare based on that name. * Windows furthermore DOES NOT have an API to get the non-localised name nor * can we override the system locale. This means that we have to actually read * the font itself to gather the font name we want. * Based on: http://blogs.msdn.com/michkap/archive/2006/02/13/530814.aspx * @param logfont the font information to get the english name of. * @return the English name (if it could be found). */ static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont) { static char font_name[MAX_PATH]; const char *ret_font_name = NULL; uint pos = 0; HDC dc; HGDIOBJ oldfont; byte *buf; DWORD dw; uint16 format, count, stringOffset, platformId, encodingId, languageId, nameId, length, offset; HFONT font = CreateFontIndirect(&logfont->elfLogFont); if (font == NULL) goto err1; dc = GetDC(NULL); oldfont = SelectObject(dc, font); dw = GetFontData(dc, 'eman', 0, NULL, 0); if (dw == GDI_ERROR) goto err2; buf = MallocT<byte>(dw); dw = GetFontData(dc, 'eman', 0, buf, dw); if (dw == GDI_ERROR) goto err3; format = buf[pos++] << 8; format += buf[pos++]; assert(format == 0); count = buf[pos++] << 8; count += buf[pos++]; stringOffset = buf[pos++] << 8; stringOffset += buf[pos++]; for (uint i = 0; i < count; i++) { platformId = buf[pos++] << 8; platformId += buf[pos++]; encodingId = buf[pos++] << 8; encodingId += buf[pos++]; languageId = buf[pos++] << 8; languageId += buf[pos++]; nameId = buf[pos++] << 8; nameId += buf[pos++]; if (nameId != 1) { pos += 4; // skip length and offset continue; } length = buf[pos++] << 8; length += buf[pos++]; offset = buf[pos++] << 8; offset += buf[pos++]; /* Don't buffer overflow */ length = min(length, MAX_PATH - 1); for (uint j = 0; j < length; j++) font_name[j] = buf[stringOffset + offset + j]; font_name[length] = '\0'; if ((platformId == 1 && languageId == 0) || // Macintosh English (platformId == 3 && languageId == 0x0409)) { // Microsoft English (US) ret_font_name = font_name; break; } } err3: free(buf); err2: SelectObject(dc, oldfont); ReleaseDC(NULL, dc); DeleteObject(font); err1: return ret_font_name == NULL ? WIDE_TO_MB((const TCHAR*)logfont->elfFullName) : ret_font_name; }
FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) { FT_Error err = FT_Err_Cannot_Open_Resource; HKEY hKey; LONG ret; TCHAR vbuffer[MAX_PATH], dbuffer[256]; TCHAR *font_namep; char *font_path; uint index; /* On windows NT (2000, NT3.5, XP, etc.) the fonts are stored in the * "Windows NT" key, on Windows 9x in the Windows key. To save us having * to retrieve the windows version, we'll just query both */ ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_NT), 0, KEY_READ, &hKey); if (ret != ERROR_SUCCESS) ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_9X), 0, KEY_READ, &hKey); if (ret != ERROR_SUCCESS) { DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows (NT)\\CurrentVersion\\Fonts"); return err; } /* For Unicode we need some conversion between widechar and * normal char to match the data returned by RegEnumValue, * otherwise just use parameter */ #if defined(UNICODE) font_namep = MallocT<TCHAR>(MAX_PATH); MB_TO_WIDE_BUFFER(font_name, font_namep, MAX_PATH * sizeof(TCHAR)); #else font_namep = const_cast<char *>(font_name); // only cast because in unicode pointer is not const #endif for (index = 0;; index++) { TCHAR *s; DWORD vbuflen = lengthof(vbuffer); DWORD dbuflen = lengthof(dbuffer); ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, NULL, NULL, (byte*)dbuffer, &dbuflen); if (ret != ERROR_SUCCESS) goto registry_no_font_found; /* The font names in the registry are of the following 3 forms: * - ADMUI3.fon * - Book Antiqua Bold (TrueType) * - Batang & BatangChe & Gungsuh & GungsuhChe (TrueType) * We will strip the font-type '()' if any and work with the font name * itself, which must match exactly; if... * TTC files, font files which contain more than one font are separated * by '&'. Our best bet will be to do substr match for the fontname * and then let FreeType figure out which index to load */ s = _tcschr(vbuffer, _T('(')); if (s != NULL) s[-1] = '\0'; if (_tcschr(vbuffer, _T('&')) == NULL) { if (_tcsicmp(vbuffer, font_namep) == 0) break; } else { if (_tcsstr(vbuffer, font_namep) != NULL) break; } } if (!SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) { DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory"); goto folder_error; } /* Some fonts are contained in .ttc files, TrueType Collection fonts. These * contain multiple fonts inside this single file. GetFontData however * returns the whole file, so we need to check each font inside to get the * proper font. * Also note that FreeType does not support UNICODE filenames! */ #if defined(UNICODE) /* We need a cast here back from wide because FreeType doesn't support * widechar filenames. Just use the buffer we allocated before for the * font_name search */ font_path = (char*)font_namep; WIDE_TO_MB_BUFFER(vbuffer, font_path, MAX_PATH * sizeof(TCHAR)); #else font_path = vbuffer; #endif 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); if (err != FT_Err_Ok) break; if (strncasecmp(font_name, (*face)->family_name, strlen((*face)->family_name)) == 0) break; /* Try english name if font name failed */ if (strncasecmp(font_name + strlen(font_name) + 1, (*face)->family_name, strlen((*face)->family_name)) == 0) break; err = FT_Err_Cannot_Open_Resource; } while ((FT_Long)++index != (*face)->num_faces); folder_error: registry_no_font_found: #if defined(UNICODE) free(font_namep); #endif RegCloseKey(hKey); return err; }