summaryrefslogtreecommitdiff
path: root/src/fontcache.cpp
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2019-05-05 02:47:32 +0200
committerOwen Rudge <owen@owenrudge.net>2019-05-14 11:21:36 +0100
commiteeccfa2570a8571d5fd9d4525d6e9b1cbdf8110a (patch)
treeb29c64c9e738f0c1831e98636f31de6dd2a0b7da /src/fontcache.cpp
parentd2ed4260772e0a2ce8805e9c40525d0abb9345ea (diff)
downloadopenttd-eeccfa2570a8571d5fd9d4525d6e9b1cbdf8110a.tar.xz
Add: [Win32] Support for loading fonts from a file for the GDI font renderer.
Diffstat (limited to 'src/fontcache.cpp')
-rw-r--r--src/fontcache.cpp54
1 files changed, 48 insertions, 6 deletions
diff --git a/src/fontcache.cpp b/src/fontcache.cpp
index 709b8a7d6..c29c868e5 100644
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -19,6 +19,7 @@
#include "zoom_type.h"
#include "gfx_layout.h"
#include "zoom_func.h"
+#include "fileio_func.h"
#include "table/sprites.h"
#include "table/control_codes.h"
@@ -948,6 +949,8 @@ void Win32FontCache::ClearFontCache()
*/
static void LoadWin32Font(FontSize fs)
{
+ static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
+
FreeTypeSubSetting *settings = nullptr;
switch (fs) {
default: NOT_REACHED();
@@ -961,20 +964,59 @@ static void LoadWin32Font(FontSize fs)
LOGFONT logfont;
MemSetT(&logfont, 0);
- if (settings->os_handle != nullptr) logfont = *(const LOGFONT *)settings->os_handle;
+ logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
+ logfont.lfCharSet = DEFAULT_CHARSET;
+ logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
+ logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+
+ if (settings->os_handle != nullptr) {
+ logfont = *(const LOGFONT *)settings->os_handle;
+ } else if (strchr(settings->font, '.') != nullptr && FileExists(settings->font)) {
+ /* Might be a font file name, try load it. */
+ TCHAR fontPath[MAX_PATH];
+ convert_to_fs(settings->font, fontPath, lengthof(fontPath), false);
+
+ if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
+ /* Try a nice little undocumented function first for getting the internal font name.
+ * Some documentation is fount at: http://www.undocprint.org/winspool/getfontresourceinfo */
+ typedef BOOL(WINAPI * PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
+#ifdef UNICODE
+ static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(_T("Gdi32")), "GetFontResourceInfoW");
+#else
+ static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(_T("Gdi32")), "GetFontResourceInfoA");
+#endif
+
+ if (GetFontResourceInfo != nullptr) {
+ /* Try to query an array of LOGFONTs that describe the file. */
+ DWORD len = 0;
+ if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) {
+ LOGFONT *buf = (LOGFONT *)AllocaM(byte, len);
+ if (GetFontResourceInfo(fontPath, &len, buf, 2)) {
+ logfont = *buf; // Just use first entry.
+ }
+ }
+ }
+
+ /* No dice yet. Use the file name as the font face name, hoping it matches. */
+ if (logfont.lfFaceName[0] == 0) {
+ TCHAR fname[_MAX_FNAME];
+ _tsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
+
+ _tcsncpy_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.
+ }
+ } else {
+ ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", settings->font, 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.
- logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
- logfont.lfCharSet = DEFAULT_CHARSET;
- logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
- logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
}
HFONT font = CreateFontIndirect(&logfont);
if (font == nullptr) {
- static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", settings->font, SIZE_TO_NAME[fs], GetLastError());
return;
}