Update to 12.0-beta1

This commit is contained in:
dP
2021-08-15 14:57:29 +03:00
parent ac7d3eba75
commit 9df4f2c4fc
666 changed files with 61302 additions and 20466 deletions
+9 -9
View File
@@ -57,7 +57,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
}
if (os_err == noErr) {
DEBUG(freetype, 3, "Font path for %s: %s", font_name, file_path);
Debug(freetype, 3, "Font path for {}: {}", font_name, file_path);
err = FT_New_Face(_library, (const char *)file_path, 0, face);
}
@@ -134,7 +134,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
/* Save result. */
callback->SetFontNames(settings, name);
if (!callback->FindMissingGlyphs()) {
DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name);
Debug(freetype, 2, "CT-Font for {}: {}", language_isocode, name);
result = true;
break;
}
@@ -221,7 +221,7 @@ void CoreTextFontCache::SetFontSize(int pixels)
CFStringGetCString(font_name.get(), name, lengthof(name), kCFStringEncodingUTF8);
this->font_name = name;
DEBUG(freetype, 2, "Loaded font '%s' with size %d", this->font_name.c_str(), pixels);
Debug(freetype, 2, "Loaded font '{}' with size {}", this->font_name, pixels);
}
GlyphID CoreTextFontCache::MapCharToGlyph(WChar key)
@@ -359,7 +359,7 @@ void LoadCoreTextFont(FontSize fs)
case FS_MONO: settings = &_freetype.mono; break;
}
if (StrEmpty(settings->font)) return;
if (settings->font.empty()) return;
CFAutoRelease<CTFontDescriptorRef> font_ref;
@@ -375,10 +375,10 @@ void LoadCoreTextFont(FontSize fs)
/* See if this is an absolute path. */
if (FileExists(settings->font)) {
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font, kCFStringEncodingUTF8));
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8));
} else {
/* Scan the search-paths to see if it can be found. */
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
std::string full_font = FioFindFullPath(BASE_DIR, settings->font.c_str());
if (!full_font.empty()) {
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8));
}
@@ -393,13 +393,13 @@ void LoadCoreTextFont(FontSize fs)
font_ref.reset((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0));
CFRetain(font_ref.get());
} else {
ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font, SIZE_TO_NAME[fs]);
ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), SIZE_TO_NAME[fs]);
}
}
}
if (!font_ref) {
CFAutoRelease<CFStringRef> name(CFStringCreateWithCString(kCFAllocatorDefault, settings->font, kCFStringEncodingUTF8));
CFAutoRelease<CFStringRef> name(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8));
/* Simply creating the font using CTFontCreateWithNameAndSize will *always* return
* something, no matter the name. As such, we can't use it to check for existence.
@@ -417,7 +417,7 @@ void LoadCoreTextFont(FontSize fs)
}
if (!font_ref) {
ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font, SIZE_TO_NAME[fs]);
ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), SIZE_TO_NAME[fs]);
return;
}
+2 -2
View File
@@ -191,13 +191,13 @@ const char *GetCurrentLocale(const char *)
bool GetClipboardContents(char *buffer, const char *last)
{
NSPasteboard *pb = [ NSPasteboard generalPasteboard ];
NSArray *types = [ NSArray arrayWithObject:NSStringPboardType ];
NSArray *types = [ NSArray arrayWithObject:NSPasteboardTypeString ];
NSString *bestType = [ pb availableTypeFromArray:types ];
/* Clipboard has no text data available. */
if (bestType == nil) return false;
NSString *string = [ pb stringForType:NSStringPboardType ];
NSString *string = [ pb stringForType:NSPasteboardTypeString ];
if (string == nil || [ string length ] == 0) return false;
strecpy(buffer, [ string UTF8String ], last);
+6 -2
View File
@@ -26,6 +26,10 @@
#define HAVE_OSX_1011_SDK
#endif
#ifdef MAC_OS_X_VERSION_10_12
#define HAVE_OSX_1012_SDK
#endif
/* It would seem that to ensure backward compatibility we have to ensure that we have defined MAC_OS_X_VERSION_10_x everywhere */
#ifndef MAC_OS_X_VERSION_10_3
#define MAC_OS_X_VERSION_10_3 1030
@@ -73,8 +77,8 @@
#endif
/* Check for mismatching 'architectures' */
#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(_SQ64)) || (!defined(__LP64__) && defined(_SQ64)))
# error "Compiling 64 bits without _SQ64 set! (or vice versa)"
#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(POINTER_IS_64BIT)) || (!defined(__LP64__) && defined(POINTER_IS_64BIT)))
# error "Compiling 64 bits without POINTER_IS_64BIT set! (or vice versa)"
#endif
/* Name conflict */
+2 -5
View File
@@ -174,7 +174,7 @@ int CDECL main(int argc, char *argv[])
SetRandomSeed(time(nullptr));
/* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
return openttd_main(argc, argv);
}
@@ -203,13 +203,10 @@ bool GetClipboardContents(char *buffer, const char *last)
}
const char *FS2OTTD(const char *name) {return name;}
const char *OTTD2FS(const char *name) {return name;}
void OSOpenBrowser(const char *url)
{
// stub only
DEBUG(misc, 0, "Failed to open url: %s", url);
Debug(misc, 0, "Failed to open url: {}", url);
}
void SetCurrentThreadName(const char *)
+3 -3
View File
@@ -51,10 +51,10 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
/* Resolve the name and populate the information structure */
pat = FcNameParse((FcChar8 *)font_family);
if (font_style != nullptr) FcPatternAddString(pat, FC_STYLE, (FcChar8 *)font_style);
FcConfigSubstitute(0, pat, FcMatchPattern);
FcConfigSubstitute(nullptr, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
fs = FcFontSetCreate();
match = FcFontMatch(0, pat, &result);
match = FcFontMatch(nullptr, pat, &result);
if (fs != nullptr && match != nullptr) {
int i;
@@ -148,7 +148,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
callback->SetFontNames(settings, (const char *)file);
bool missing = callback->FindMissingGlyphs();
DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");
Debug(freetype, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no");
if (!missing) {
best_weight = value;
+15 -18
View File
@@ -146,9 +146,8 @@ static const char *GetLocalCode()
* Convert between locales, which from and which to is set in the calling
* functions OTTD2FS() and FS2OTTD().
*/
static const char *convert_tofrom_fs(iconv_t convd, const char *name)
static const char *convert_tofrom_fs(iconv_t convd, const char *name, char *outbuf, size_t outlen)
{
static char buf[1024];
/* There are different implementations of iconv. The older ones,
* e.g. SUSv2, pass a const pointer, whereas the newer ones, e.g.
* IEEE 1003.1 (2004), pass a non-const pointer. */
@@ -158,15 +157,14 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
const char *inbuf = name;
#endif
char *outbuf = buf;
size_t outlen = sizeof(buf) - 1;
size_t inlen = strlen(name);
char *buf = outbuf;
strecpy(outbuf, name, outbuf + outlen);
iconv(convd, nullptr, nullptr, nullptr, nullptr);
if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
Debug(misc, 0, "[iconv] error converting '{}'. Errno {}", name, errno);
}
*outbuf = '\0';
@@ -179,46 +177,45 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
* @param name pointer to a valid string that will be converted
* @return pointer to a new stringbuffer that contains the converted string
*/
const char *OTTD2FS(const char *name)
std::string OTTD2FS(const std::string &name)
{
static iconv_t convd = (iconv_t)(-1);
char buf[1024] = {};
if (convd == (iconv_t)(-1)) {
const char *env = GetLocalCode();
convd = iconv_open(env, INTERNALCODE);
if (convd == (iconv_t)(-1)) {
DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", INTERNALCODE, env);
Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", INTERNALCODE, env);
return name;
}
}
return convert_tofrom_fs(convd, name);
return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
}
/**
* Convert to OpenTTD's encoding from that of the local environment
* @param name pointer to a valid string that will be converted
* @param name valid string that will be converted
* @return pointer to a new stringbuffer that contains the converted string
*/
const char *FS2OTTD(const char *name)
std::string FS2OTTD(const std::string &name)
{
static iconv_t convd = (iconv_t)(-1);
char buf[1024] = {};
if (convd == (iconv_t)(-1)) {
const char *env = GetLocalCode();
convd = iconv_open(INTERNALCODE, env);
if (convd == (iconv_t)(-1)) {
DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", env, INTERNALCODE);
Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", env, INTERNALCODE);
return name;
}
}
return convert_tofrom_fs(convd, name);
return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
}
#else
const char *FS2OTTD(const char *name) {return name;}
const char *OTTD2FS(const char *name) {return name;}
#endif /* WITH_ICONV */
void ShowInfo(const char *str)
@@ -246,7 +243,7 @@ void CocoaReleaseAutoreleasePool();
int CDECL main(int argc, char *argv[])
{
/* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
#ifdef WITH_COCOA
CocoaSetupAutoreleasePool();
@@ -280,7 +277,7 @@ bool GetClipboardContents(char *buffer, const char *last)
}
char *clip = SDL_GetClipboardText();
if (clip != NULL) {
if (clip != nullptr) {
strecpy(buffer, clip, last);
SDL_free(clip);
return true;
@@ -309,7 +306,7 @@ void OSOpenBrowser(const char *url)
args[1] = url;
args[2] = nullptr;
execvp(args[0], const_cast<char * const *>(args));
DEBUG(misc, 0, "Failed to open url: %s", url);
Debug(misc, 0, "Failed to open url: {}", url);
exit(0);
}
#endif /* __APPLE__ */
+48 -52
View File
@@ -22,6 +22,7 @@
#include <windows.h>
#include <mmsystem.h>
#include <signal.h>
#include <psapi.h>
#include "../../safeguards.h"
@@ -189,7 +190,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
GetModuleFileName(mod, buffer, MAX_PATH);
GetFileInfo(&dfi, buffer);
output += seprintf(output, last, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\n",
FS2OTTD(buffer),
FS2OTTD(buffer).c_str(),
mod,
dfi.size,
dfi.crc32,
@@ -206,25 +207,19 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
/* virtual */ char *CrashLogWindows::LogModules(char *output, const char *last) const
{
MakeCRCTable(AllocaM(uint32, 256));
BOOL (WINAPI *EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD);
output += seprintf(output, last, "Module information:\n");
if (LoadLibraryList((Function*)&EnumProcessModules, "psapi.dll\0EnumProcessModules\0\0")) {
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
if (proc != nullptr) {
HMODULE modules[100];
DWORD needed;
BOOL res;
BOOL res = EnumProcessModules(proc, modules, sizeof(modules), &needed);
CloseHandle(proc);
if (res) {
size_t count = std::min<DWORD>(needed / sizeof(HMODULE), lengthof(modules));
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
if (proc != nullptr) {
res = EnumProcessModules(proc, modules, sizeof(modules), &needed);
CloseHandle(proc);
if (res) {
size_t count = std::min<DWORD>(needed / sizeof(HMODULE), lengthof(modules));
for (size_t i = 0; i != count; i++) output = PrintModuleInfo(output, last, modules[i]);
return output + seprintf(output, last, "\n");
}
for (size_t i = 0; i != count; i++) output = PrintModuleInfo(output, last, modules[i]);
return output + seprintf(output, last, "\n");
}
}
output = PrintModuleInfo(output, last, nullptr);
@@ -373,22 +368,7 @@ static const uint MAX_FRAMES = 64;
char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) const
{
#define M(x) x "\0"
static const char dbg_import[] =
M("dbghelp.dll")
M("SymInitialize")
M("SymSetOptions")
M("SymCleanup")
M("StackWalk64")
M("SymFunctionTableAccess64")
M("SymGetModuleBase64")
M("SymGetModuleInfo64")
M("SymGetSymFromAddr64")
M("SymGetLineFromAddr64")
M("")
;
#undef M
DllLoader dbghelp(L"dbghelp.dll");
struct ProcPtrs {
BOOL (WINAPI * pSymInitialize)(HANDLE, PCSTR, BOOL);
BOOL (WINAPI * pSymSetOptions)(DWORD);
@@ -399,12 +379,22 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
BOOL (WINAPI * pSymGetModuleInfo64)(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
BOOL (WINAPI * pSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
} proc;
} proc = {
dbghelp.GetProcAddress("SymInitialize"),
dbghelp.GetProcAddress("SymSetOptions"),
dbghelp.GetProcAddress("SymCleanup"),
dbghelp.GetProcAddress("StackWalk64"),
dbghelp.GetProcAddress("SymFunctionTableAccess64"),
dbghelp.GetProcAddress("SymGetModuleBase64"),
dbghelp.GetProcAddress("SymGetModuleInfo64"),
dbghelp.GetProcAddress("SymGetSymFromAddr64"),
dbghelp.GetProcAddress("SymGetLineFromAddr64"),
};
buffer += seprintf(buffer, last, "\nDecoded stack trace:\n");
/* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */
if (LoadLibraryList((Function*)&proc, dbg_import)) {
if (dbghelp.Success()) {
/* Initialize symbol handler. */
HANDLE hCur = GetCurrentProcess();
proc.pSymInitialize(hCur, nullptr, TRUE);
@@ -491,17 +481,17 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
/* virtual */ int CrashLogWindows::WriteCrashDump(char *filename, const char *filename_last) const
{
int ret = 0;
HMODULE dbghelp = LoadLibrary(L"dbghelp.dll");
if (dbghelp != nullptr) {
DllLoader dbghelp(L"dbghelp.dll");
if (dbghelp.Success()) {
typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
MINIDUMP_TYPE,
CONST PMINIDUMP_EXCEPTION_INFORMATION,
CONST PMINIDUMP_USER_STREAM_INFORMATION,
CONST PMINIDUMP_CALLBACK_INFORMATION);
MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump");
MiniDumpWriteDump_t funcMiniDumpWriteDump = dbghelp.GetProcAddress("MiniDumpWriteDump");
if (funcMiniDumpWriteDump != nullptr) {
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
HANDLE proc = GetCurrentProcess();
DWORD procid = GetCurrentProcessId();
MINIDUMP_EXCEPTION_INFORMATION mdei;
@@ -524,7 +514,6 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
} else {
ret = -1;
}
FreeLibrary(dbghelp);
}
return ret;
}
@@ -638,7 +627,7 @@ static void CDECL CustomAbort(int signal)
mov safe_esp, esp
}
# else
asm("movl %esp, _safe_esp");
asm("movl %%esp, %0" : "=rm" (safe_esp));
# endif
_safe_esp = safe_esp;
#endif
@@ -689,7 +678,8 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
switch (msg) {
case WM_INITDIALOG: {
/* We need to put the crash-log in a separate buffer because the default
* buffer in OTTD2FS is not large enough (512 chars) */
* buffer in MB_TO_WIDE is not large enough (512 chars) */
wchar_t filenamebuf[MAX_PATH * 2];
wchar_t crash_msgW[lengthof(CrashLogWindows::current->crashlog)];
/* Convert unix -> dos newlines because the edit box only supports that properly :( */
const char *unix_nl = CrashLogWindows::current->crashlog;
@@ -704,19 +694,23 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
/* Add path to crash.log and crash.dmp (if any) to the crash window text */
size_t len = wcslen(_crash_desc) + 2;
len += wcslen(OTTD2FS(CrashLogWindows::current->crashlog_filename)) + 2;
len += wcslen(OTTD2FS(CrashLogWindows::current->crashdump_filename)) + 2;
len += wcslen(OTTD2FS(CrashLogWindows::current->screenshot_filename)) + 1;
len += wcslen(convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf))) + 2;
len += wcslen(convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))) + 2;
len += wcslen(convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))) + 1;
wchar_t *text = AllocaM(wchar_t, len);
_snwprintf(text, len, _crash_desc, OTTD2FS(CrashLogWindows::current->crashlog_filename));
if (OTTD2FS(CrashLogWindows::current->crashdump_filename)[0] != L'\0') {
wcscat(text, L"\n");
wcscat(text, OTTD2FS(CrashLogWindows::current->crashdump_filename));
int printed = _snwprintf(text, len, _crash_desc, convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf)));
if (printed < 0 || (size_t)printed > len) {
MessageBox(wnd, L"Catastrophic failure trying to display crash message. Could not perform text formatting.", L"OpenTTD", MB_ICONERROR);
return FALSE;
}
if (OTTD2FS(CrashLogWindows::current->screenshot_filename)[0] != L'\0') {
if (convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))[0] != L'\0') {
wcscat(text, L"\n");
wcscat(text, OTTD2FS(CrashLogWindows::current->screenshot_filename));
wcscat(text, filenamebuf);
}
if (convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))[0] != L'\0') {
wcscat(text, L"\n");
wcscat(text, filenamebuf);
}
SetDlgItemText(wnd, 10, text);
@@ -730,18 +724,20 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
CrashLog::AfterCrashLogCleanup();
ExitProcess(2);
case 13: // Emergency save
wchar_t filenamebuf[MAX_PATH * 2];
char filename[MAX_PATH];
if (CrashLogWindows::current->WriteSavegame(filename, lastof(filename))) {
size_t len = wcslen(_save_succeeded) + wcslen(OTTD2FS(filename)) + 1;
convert_to_fs(filename, filenamebuf, lengthof(filenamebuf));
size_t len = lengthof(_save_succeeded) + wcslen(filenamebuf) + 1;
wchar_t *text = AllocaM(wchar_t, len);
_snwprintf(text, len, _save_succeeded, OTTD2FS(filename));
_snwprintf(text, len, _save_succeeded, filenamebuf);
MessageBox(wnd, text, L"Save successful", MB_ICONINFORMATION);
} else {
MessageBox(wnd, L"Save failed", L"Save failed", MB_ICONINFORMATION);
}
break;
case 15: // Expand window to show crash-message
_expanded ^= 1;
_expanded = !_expanded;
SetWndSize(wnd, _expanded);
break;
}
+24 -21
View File
@@ -78,12 +78,12 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, FONT_DIR_NT, 0, KEY_READ, &hKey);
if (ret != ERROR_SUCCESS) {
DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
Debug(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
return err;
}
/* Convert font name to file system encoding. */
wchar_t *font_namep = wcsdup(OTTD2FS(font_name));
wchar_t *font_namep = wcsdup(OTTD2FS(font_name).c_str());
for (index = 0;; index++) {
wchar_t *s;
@@ -113,7 +113,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
}
if (!SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_FONTS, nullptr, SHGFP_TYPE_CURRENT, vbuffer))) {
DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
Debug(freetype, 0, "SHGetFolderPath cannot return fonts directory");
goto folder_error;
}
@@ -334,17 +334,17 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
info->callback->SetFontNames(info->settings, font_name, &logfont->elfLogFont);
if (info->callback->FindMissingGlyphs()) return 1;
DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
Debug(freetype, 1, "Fallback font: {} ({})", font_name, english_name);
return 0; // stop enumerating
}
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
{
DEBUG(freetype, 1, "Trying fallback fonts");
Debug(freetype, 1, "Trying fallback fonts");
EFCParam langInfo;
if (GetLocaleInfo(MAKELCID(winlangid, SORT_DEFAULT), LOCALE_FONTSIGNATURE, (LPTSTR)&langInfo.locale, sizeof(langInfo.locale) / sizeof(wchar_t)) == 0) {
/* Invalid langid or some other mysterious error, can't determine fallback font. */
DEBUG(freetype, 1, "Can't get locale info for fallback font (langid=0x%x)", winlangid);
Debug(freetype, 1, "Can't get locale info for fallback font (langid=0x{:x})", winlangid);
return false;
}
langInfo.settings = settings;
@@ -377,6 +377,7 @@ Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels)
{
this->dc = CreateCompatibleDC(nullptr);
this->SetFontSize(fs, pixels);
this->fontname = FS2OTTD(this->logfont.lfFaceName);
}
Win32FontCache::~Win32FontCache()
@@ -438,7 +439,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels)
this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth;
this->glyph_size.cy = otm->otmTextMetrics.tmHeight;
DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
Debug(freetype, 2, "Loaded font '{}' with size {}", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
}
/**
@@ -541,10 +542,10 @@ void Win32FontCache::ClearFontCache()
/* Convert characters outside of the BMP into surrogate pairs. */
WCHAR chars[2];
if (key >= 0x010000U) {
chars[0] = (WCHAR)(((key - 0x010000U) >> 10) + 0xD800);
chars[1] = (WCHAR)(((key - 0x010000U) & 0x3FF) + 0xDC00);
chars[0] = (wchar_t)(((key - 0x010000U) >> 10) + 0xD800);
chars[1] = (wchar_t)(((key - 0x010000U) & 0x3FF) + 0xDC00);
} else {
chars[0] = (WCHAR)(key & 0xFFFF);
chars[0] = (wchar_t)(key & 0xFFFF);
}
WORD glyphs[2] = { 0, 0 };
@@ -587,8 +588,9 @@ void LoadWin32Font(FontSize fs)
default: NOT_REACHED();
}
if (StrEmpty(settings->font)) return;
if (settings->font.empty()) return;
const char *font_name = settings->font.c_str();
LOGFONT logfont;
MemSetT(&logfont, 0);
logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
@@ -598,19 +600,19 @@ void LoadWin32Font(FontSize fs)
if (settings->os_handle != nullptr) {
logfont = *(const LOGFONT *)settings->os_handle;
} else if (strchr(settings->font, '.') != nullptr) {
} else if (strchr(font_name, '.') != nullptr) {
/* Might be a font file name, try load it. */
wchar_t fontPath[MAX_PATH] = {};
/* See if this is an absolute path. */
if (FileExists(settings->font)) {
convert_to_fs(settings->font, fontPath, lengthof(fontPath), false);
convert_to_fs(font_name, fontPath, lengthof(fontPath));
} else {
/* Scan the search-paths to see if it can be found. */
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
if (!full_font.empty()) {
convert_to_fs(full_font.c_str(), fontPath, lengthof(fontPath), false);
convert_to_fs(font_name, fontPath, lengthof(fontPath));
}
}
@@ -618,8 +620,9 @@ void LoadWin32Font(FontSize fs)
if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
/* Try a nice little undocumented function first for getting the internal font name.
* Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */
static DllLoader _gdi32(L"gdi32.dll");
typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(L"Gdi32"), "GetFontResourceInfoW");
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetProcAddress("GetFontResourceInfoW");
if (GetFontResourceInfo != nullptr) {
/* Try to query an array of LOGFONTs that describe the file. */
@@ -638,22 +641,22 @@ void LoadWin32Font(FontSize fs)
_wsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE);
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr || strcasestr(settings->font, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
logfont.lfWeight = strcasestr(font_name, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
}
} else {
ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", settings->font, SIZE_TO_NAME[fs]);
ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, SIZE_TO_NAME[fs]);
}
}
}
if (logfont.lfFaceName[0] == 0) {
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
logfont.lfWeight = strcasestr(font_name, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
convert_to_fs(font_name, logfont.lfFaceName, lengthof(logfont.lfFaceName));
}
HFONT font = CreateFontIndirect(&logfont);
if (font == nullptr) {
ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", settings->font, SIZE_TO_NAME[fs], GetLastError());
ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, SIZE_TO_NAME[fs], GetLastError());
return;
}
DeleteObject(font);
+2 -1
View File
@@ -21,6 +21,7 @@ private:
HDC dc = nullptr; ///< Cached GDI device context.
HGDIOBJ old_font; ///< Old font selected into the GDI context.
SIZE glyph_size; ///< Maximum size of regular glyphs.
std::string fontname; ///< Cached copy of this->logfont.lfFaceName
void SetFontSize(FontSize fs, int pixels);
@@ -33,7 +34,7 @@ public:
~Win32FontCache();
void ClearFontCache() override;
GlyphID MapCharToGlyph(WChar key) override;
const char *GetFontName() override { return FS2OTTD(this->logfont.lfFaceName); }
const char *GetFontName() override { return this->fontname.c_str(); }
const void *GetOSHandle() override { return &this->logfont; }
};
+2 -2
View File
@@ -77,8 +77,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION ${REV_MAJOR},${REV_MINOR},${REV_BUILD},${REV_ISODATE}
PRODUCTVERSION ${REV_MAJOR},${REV_MINOR},${REV_BUILD},${REV_ISODATE}
FILEVERSION ${REV_MAJOR},${REV_MINOR},0,${REV_ISODATE}
PRODUCTVERSION ${REV_MAJOR},${REV_MINOR},0,${REV_ISODATE}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
+1 -1
View File
@@ -144,7 +144,7 @@ void UniscribeResetScriptCache(FontSize size)
/** Load the matching native Windows font. */
static HFONT HFontFromFont(Font *font)
{
if (font->fc->GetOSHandle() != nullptr) return CreateFontIndirect((const PLOGFONT)font->fc->GetOSHandle());
if (font->fc->GetOSHandle() != nullptr) return CreateFontIndirect(reinterpret_cast<PLOGFONT>(const_cast<void *>(font->fc->GetOSHandle())));
LOGFONT logfont;
ZeroMemory(&logfont, sizeof(LOGFONT));
+42 -90
View File
@@ -50,39 +50,15 @@ bool MyShowCursor(bool show, bool toggle)
return !show;
}
/**
* Helper function needed by dynamically loading libraries
*/
bool LoadLibraryList(Function proc[], const char *dll)
{
while (*dll != '\0') {
HMODULE lib;
lib = LoadLibrary(OTTD2FS(dll));
if (lib == nullptr) return false;
for (;;) {
FARPROC p;
while (*dll++ != '\0') { /* Nothing */ }
if (*dll == '\0') break;
p = GetProcAddress(lib, dll);
if (p == nullptr) return false;
*proc++ = (Function)p;
}
dll++;
}
return true;
}
void ShowOSErrorBox(const char *buf, bool system)
{
MyShowCursor(true);
MessageBox(GetActiveWindow(), OTTD2FS(buf), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
MessageBox(GetActiveWindow(), OTTD2FS(buf).c_str(), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
}
void OSOpenBrowser(const char *url)
{
ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url), nullptr, nullptr, SW_SHOWNORMAL);
ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
/* Code below for windows version of opendir/readdir/closedir copied and
@@ -141,14 +117,14 @@ DIR *opendir(const wchar_t *path)
if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) {
d = dir_calloc();
if (d != nullptr) {
wchar_t search_path[MAX_PATH];
std::wstring search_path = path;
bool slash = path[wcslen(path) - 1] == '\\';
/* build search path for FindFirstFile, try not to append additional slashes
* as it throws Win9x off its groove for root directories */
_snwprintf(search_path, lengthof(search_path), L"%s%s*", path, slash ? L"" : L"\\");
*lastof(search_path) = '\0';
d->hFind = FindFirstFile(search_path, &d->fd);
if (!slash) search_path += L"\\";
search_path += L"*";
d->hFind = FindFirstFile(search_path.c_str(), &d->fd);
if (d->hFind != INVALID_HANDLE_VALUE ||
GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty
@@ -209,7 +185,7 @@ void FiosGetDrives(FileList &file_list)
GetLogicalDriveStrings(lengthof(drives), drives);
for (s = drives; *s != '\0';) {
FiosItem *fios = file_list.Append();
FiosItem *fios = &file_list.emplace_back();
fios->type = FIOS_TYPE_DRIVE;
fios->mtime = 0;
seprintf(fios->name, lastof(fios->name), "%c:", s[0] & 0xFF);
@@ -246,7 +222,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
ULARGE_INTEGER bytes_free;
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path), &bytes_free, nullptr, nullptr);
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path).c_str(), &bytes_free, nullptr, nullptr);
if (retval && tot != nullptr) *tot = bytes_free.QuadPart;
SetErrorMode(sem); // reset previous setting
@@ -415,7 +391,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
/* Convert the command line to UTF-8. We need a dedicated buffer
* for this because argv[] points into this buffer and this needs to
* be available between subsequent calls to FS2OTTD(). */
char *cmdline = stredup(FS2OTTD(GetCommandLine()));
char *cmdline = stredup(FS2OTTD(GetCommandLine()).c_str());
/* Set the console codepage to UTF-8. */
SetConsoleOutputCP(CP_UTF8);
#if defined(_DEBUG)
CreateConsole();
@@ -429,7 +408,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
argc = ParseCommandLine(cmdline, argv, lengthof(argv));
/* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
openttd_main(argc, argv);
@@ -495,7 +474,7 @@ void DetermineBasePaths(const char *exe)
wchar_t config_dir[MAX_PATH];
wcsncpy(path, convert_to_fs(_config_file.c_str(), path, lengthof(path)), lengthof(path));
if (!GetFullPathName(path, lengthof(config_dir), config_dir, nullptr)) {
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
Debug(misc, 0, "GetFullPathName failed ({})", GetLastError());
_searchpaths[SP_WORKING_DIR].clear();
} else {
std::string tmp(FS2OTTD(config_dir));
@@ -507,13 +486,13 @@ void DetermineBasePaths(const char *exe)
}
if (!GetModuleFileName(nullptr, path, lengthof(path))) {
DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError());
Debug(misc, 0, "GetModuleFileName failed ({})", GetLastError());
_searchpaths[SP_BINARY_DIR].clear();
} else {
wchar_t exec_dir[MAX_PATH];
wcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path));
if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, nullptr)) {
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
Debug(misc, 0, "GetFullPathName failed ({})", GetLastError());
_searchpaths[SP_BINARY_DIR].clear();
} else {
std::string tmp(FS2OTTD(exec_dir));
@@ -553,34 +532,40 @@ bool GetClipboardContents(char *buffer, const char *last)
/**
* Convert to OpenTTD's encoding from wide characters.
* Convert to OpenTTD's encoding from a wide string.
* OpenTTD internal encoding is UTF8.
* The returned value's contents can only be guaranteed until the next call to
* this function. So if the value is needed for anything else, use convert_from_fs
* @param name pointer to a valid string that will be converted (local, or wide)
* @return pointer to the converted string; if failed string is of zero-length
* @param name valid string that will be converted (local, or wide)
* @return converted string; if failed string is of zero-length
* @see the current code-page comes from video\win32_v.cpp, event-notification
* WM_INPUTLANGCHANGE
*/
const char *FS2OTTD(const wchar_t *name)
std::string FS2OTTD(const std::wstring &name)
{
static char utf8_buf[512];
return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0, nullptr, nullptr);
if (len <= 0) return std::string();
char *utf8_buf = AllocaM(char, len + 1);
utf8_buf[len] = '\0';
WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, utf8_buf, len, nullptr, nullptr);
return std::string(utf8_buf, static_cast<size_t>(len));
}
/**
* Convert from OpenTTD's encoding to wide characters.
* Convert from OpenTTD's encoding to a wide string.
* OpenTTD internal encoding is UTF8.
* The returned value's contents can only be guaranteed until the next call to
* this function. So if the value is needed for anything else, use convert_from_fs
* @param name pointer to a valid string that will be converted (UTF8)
* @param name valid string that will be converted (UTF8)
* @param console_cp convert to the console encoding instead of the normal system encoding.
* @return pointer to the converted string; if failed string is of zero-length
* @return converted string; if failed string is of zero-length
*/
const wchar_t *OTTD2FS(const char *name, bool console_cp)
std::wstring OTTD2FS(const std::string &name)
{
static wchar_t system_buf[512];
return convert_to_fs(name, system_buf, lengthof(system_buf), console_cp);
int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0);
if (len <= 0) return std::wstring();
wchar_t *system_buf = AllocaM(wchar_t, len + 1);
system_buf[len] = L'\0';
MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, system_buf, len);
return std::wstring(system_buf, static_cast<size_t>(len));
}
@@ -594,10 +579,8 @@ const wchar_t *OTTD2FS(const char *name, bool console_cp)
*/
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
{
const wchar_t *wide_buf = name;
/* Convert UTF-16 string to UTF-8. */
int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, nullptr, nullptr);
int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, nullptr, nullptr);
if (len == 0) utf8_buf[0] = '\0';
return utf8_buf;
@@ -614,7 +597,7 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
* @param console_cp convert to the console encoding instead of the normal system encoding.
* @return pointer to system_buf. If conversion fails the string is of zero-length
*/
wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen, bool console_cp)
wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen)
{
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, system_buf, (int)buflen);
if (len == 0) system_buf[0] = '\0';
@@ -675,7 +658,8 @@ int OTTDStringCompare(const char *s1, const char *s2)
#endif
if (first_time) {
_CompareStringEx = (PFNCOMPARESTRINGEX)GetProcAddress(GetModuleHandle(L"Kernel32"), "CompareStringEx");
static DllLoader _kernel32(L"Kernel32.dll");
_CompareStringEx = _kernel32.GetProcAddress("CompareStringEx");
first_time = false;
}
@@ -703,38 +687,6 @@ int OTTDStringCompare(const char *s1, const char *s2)
return CompareString(MAKELCID(_current_language->winlangid, SORT_DEFAULT), NORM_IGNORECASE, s1_buf, -1, s2_buf, -1);
}
/**
* Is the current Windows version Vista or later?
* @return True if the current Windows is Vista or later.
*/
bool IsWindowsVistaOrGreater()
{
typedef BOOL (WINAPI * LPVERIFYVERSIONINFO)(LPOSVERSIONINFOEX, DWORD, DWORDLONG);
typedef ULONGLONG (NTAPI * LPVERSETCONDITIONMASK)(ULONGLONG, DWORD, BYTE);
#ifdef UNICODE
static LPVERIFYVERSIONINFO _VerifyVersionInfo = (LPVERIFYVERSIONINFO)GetProcAddress(GetModuleHandle(_T("Kernel32")), "VerifyVersionInfoW");
#else
static LPVERIFYVERSIONINFO _VerifyVersionInfo = (LPVERIFYVERSIONINFO)GetProcAddress(GetModuleHandle(_T("Kernel32")), "VerifyVersionInfoA");
#endif
static LPVERSETCONDITIONMASK _VerSetConditionMask = (LPVERSETCONDITIONMASK)GetProcAddress(GetModuleHandle(_T("Kernel32")), "VerSetConditionMask");
if (_VerifyVersionInfo != nullptr && _VerSetConditionMask != nullptr) {
OSVERSIONINFOEX osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
DWORDLONG dwlConditionMask = 0;
dwlConditionMask = _VerSetConditionMask(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
dwlConditionMask = _VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
dwlConditionMask = _VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = 6;
osvi.dwMinorVersion = 0;
osvi.wServicePackMajor = 0;
return _VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
} else {
return LOBYTE(GetVersion()) >= 6;
}
}
#ifdef _MSC_VER
/* Based on code from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */
const DWORD MS_VC_EXCEPTION = 0x406D1388;
+42 -8
View File
@@ -13,18 +13,52 @@
#include <windows.h>
bool MyShowCursor(bool show, bool toggle = false);
typedef void (*Function)(int);
bool LoadLibraryList(Function proc[], const char *dll);
class DllLoader {
public:
explicit DllLoader(LPCTSTR filename)
{
this->hmodule = ::LoadLibrary(filename);
if (this->hmodule == nullptr) this->success = false;
}
~DllLoader()
{
::FreeLibrary(this->hmodule);
}
bool Success() { return this->success; }
class ProcAddress {
public:
explicit ProcAddress(void *p) : p(p) {}
template <typename T, typename = std::enable_if_t<std::is_function_v<T>>>
operator T *() const
{
return reinterpret_cast<T *>(this->p);
}
private:
void *p;
};
ProcAddress GetProcAddress(const char *proc_name)
{
void *p = reinterpret_cast<void *>(::GetProcAddress(this->hmodule, proc_name));
if (p == nullptr) this->success = false;
return ProcAddress(p);
}
private:
HMODULE hmodule = nullptr;
bool success = true;
};
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen, bool console_cp = false);
#if defined(__MINGW32__) && !defined(__MINGW64__)
#define SHGFP_TYPE_CURRENT 0
#endif /* __MINGW32__ */
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
void Win32SetCurrentLocaleName(const char *iso_code);
int OTTDStringCompare(const char *s1, const char *s2);
bool IsWindowsVistaOrGreater();
#endif /* WIN32_H */