void DetermineBasePaths(const char *exe) { char tmp[MAX_PATH]; TCHAR path[MAX_PATH]; #ifdef WITH_PERSONAL_DIR if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp)); AppendPathSeparator(tmp, MAX_PATH); ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH); AppendPathSeparator(tmp, MAX_PATH); _searchpaths[SP_PERSONAL_DIR] = strdup(tmp); } else { _searchpaths[SP_PERSONAL_DIR] = NULL; } if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp)); AppendPathSeparator(tmp, MAX_PATH); ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH); AppendPathSeparator(tmp, MAX_PATH); _searchpaths[SP_SHARED_DIR] = strdup(tmp); } else { _searchpaths[SP_SHARED_DIR] = NULL; } #else _searchpaths[SP_PERSONAL_DIR] = NULL; _searchpaths[SP_SHARED_DIR] = NULL; #endif /* Get the path to working directory of OpenTTD */ getcwd(tmp, lengthof(tmp)); AppendPathSeparator(tmp, MAX_PATH); _searchpaths[SP_WORKING_DIR] = strdup(tmp); if (!GetModuleFileName(NULL, path, lengthof(path))) { DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { TCHAR exec_dir[MAX_PATH]; _tcsncpy(path, MB_TO_WIDE_BUFFER(exe, path, lengthof(path)), lengthof(path)); if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) { DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { strecpy(tmp, WIDE_TO_MB_BUFFER(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); char *s = strrchr(tmp, PATHSEPCHAR); *(s + 1) = '\0'; _searchpaths[SP_BINARY_DIR] = strdup(tmp); } } _searchpaths[SP_INSTALLATION_DIR] = NULL; _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) #endif { int argc; char *argv[64]; // max 64 command line arguments char *cmdline; #if !defined(UNICODE) _codepage = GetACP(); // get system codepage as some kind of a default #endif /* UNICODE */ CrashLog::InitialiseCrashLog(); #if defined(UNICODE) #if !defined(WINCE) /* Check if a win9x user started the win32 version */ if (HasBit(GetVersion(), 31)) usererror("This version of OpenTTD doesn't run on windows 95/98/ME.\nPlease download the win9x binary and try again."); #endif /* For UNICODE we need to convert the commandline to char* _AND_ * save it because argv[] points into this buffer and thus needs to * be available between subsequent calls to FS2OTTD() */ char cmdlinebuf[MAX_PATH]; #endif /* UNICODE */ cmdline = WIDE_TO_MB_BUFFER(GetCommandLine(), cmdlinebuf, lengthof(cmdlinebuf)); #if defined(_DEBUG) CreateConsole(); #endif #if !defined(WINCE) _set_error_mode(_OUT_TO_MSGBOX); // force assertion output to messagebox #endif /* setup random seed to something quite random */ SetRandomSeed(GetTickCount()); argc = ParseCommandLine(cmdline, argv, lengthof(argv)); ttd_main(argc, argv); return 0; }
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; }
static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam) { EFCParam *info = (EFCParam *)lParam; /* Skip duplicates */ if (!info->fonts.Add((const TCHAR*)logfont->elfFullName)) return 1; /* Only use TrueType fonts */ if (!(type & TRUETYPE_FONTTYPE)) return 1; /* Don't use SYMBOL fonts */ if (logfont->elfLogFont.lfCharSet == SYMBOL_CHARSET) return 1; /* Use monospaced fonts when asked for it. */ if (info->callback->Monospace() && (logfont->elfLogFont.lfPitchAndFamily & (FF_MODERN | FIXED_PITCH)) != (FF_MODERN | FIXED_PITCH)) 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; } char font_name[MAX_PATH]; #if defined(UNICODE) WIDE_TO_MB_BUFFER((const TCHAR*)logfont->elfFullName, font_name, lengthof(font_name)); #else strecpy(font_name, (const TCHAR*)logfont->elfFullName, lastof(font_name)); #endif /* Add english name after font name */ const char *english_name = GetEnglishFontName(logfont); strecpy(font_name + strlen(font_name) + 1, english_name, lastof(font_name)); /* Check whether we can actually load the font. */ bool ft_init = _library != NULL; bool found = false; FT_Face face; /* Init FreeType if needed. */ if ((ft_init || FT_Init_FreeType(&_library) == FT_Err_Ok) && GetFontByFaceName(font_name, &face) == FT_Err_Ok) { FT_Done_Face(face); found = true; } if (!ft_init) { /* Uninit FreeType if we did the init. */ FT_Done_FreeType(_library); _library = NULL; } if (!found) return 1; info->callback->SetFontNames(info->settings, font_name); if (info->callback->FindMissingGlyphs(NULL)) return 1; DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name); return 0; // stop enumerating }