mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-18 20:43:04 +01:00
Upgrade platform_get_font_path()
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
# include "../core/String.hpp"
|
||||
# include "../localisation/Localisation.h"
|
||||
# include "../localisation/LocalisationService.h"
|
||||
# include "../platform/Platform2.h"
|
||||
# include "../platform/platform.h"
|
||||
# include "TTF.h"
|
||||
|
||||
@@ -125,17 +126,17 @@ bool ttf_initialise()
|
||||
{
|
||||
TTFFontDescriptor* fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
|
||||
utf8 fontPath[MAX_PATH];
|
||||
if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath)))
|
||||
auto fontPath = Platform::GetFontPath(*fontDesc);
|
||||
if (fontPath.empty())
|
||||
{
|
||||
log_verbose("Unable to load font '%s'", fontDesc->font_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
fontDesc->font = ttf_open_font(fontPath, fontDesc->ptSize);
|
||||
fontDesc->font = ttf_open_font(fontPath.c_str(), fontDesc->ptSize);
|
||||
if (fontDesc->font == nullptr)
|
||||
{
|
||||
log_verbose("Unable to load '%s'", fontPath);
|
||||
log_verbose("Unable to load '%s'", fontPath.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,6 @@
|
||||
# include <jni.h>
|
||||
# include <wchar.h>
|
||||
|
||||
# ifndef NO_TTF
|
||||
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
|
||||
{
|
||||
STUB();
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
float platform_get_default_scale()
|
||||
{
|
||||
JNIEnv* env = static_cast<JNIEnv*>(SDL_AndroidGetJNIEnv());
|
||||
|
||||
@@ -34,67 +34,4 @@
|
||||
|
||||
# include <pwd.h>
|
||||
|
||||
# ifndef NO_TTF
|
||||
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
|
||||
{
|
||||
assert(buffer != nullptr);
|
||||
assert(font != nullptr);
|
||||
|
||||
log_verbose("Looking for font %s with FontConfig.", font->font_name);
|
||||
FcConfig* config = FcInitLoadConfigAndFonts();
|
||||
if (!config)
|
||||
{
|
||||
log_error("Failed to initialize FontConfig library");
|
||||
FcFini();
|
||||
return false;
|
||||
}
|
||||
|
||||
FcPattern* pat = FcNameParse(reinterpret_cast<const FcChar8*>(font->font_name));
|
||||
|
||||
FcConfigSubstitute(config, pat, FcMatchPattern);
|
||||
FcDefaultSubstitute(pat);
|
||||
|
||||
bool found = false;
|
||||
FcResult result = FcResultNoMatch;
|
||||
FcPattern* match = FcFontMatch(config, pat, &result);
|
||||
|
||||
if (match)
|
||||
{
|
||||
bool is_substitute = false;
|
||||
|
||||
// FontConfig implicitly falls back to any default font it is configured to handle.
|
||||
// In our implementation, this cannot account for supported character sets, leading
|
||||
// to unrendered characters (tofu) when trying to render e.g. CJK characters using a
|
||||
// Western (sans-)serif font. We therefore ignore substitutions FontConfig provides,
|
||||
// and instead rely on exact matches on the fonts predefined for each font family.
|
||||
FcChar8* matched_font_face = nullptr;
|
||||
if (FcPatternGetString(match, FC_FULLNAME, 0, &matched_font_face) == FcResultMatch
|
||||
&& strcmp(font->font_name, reinterpret_cast<const char*>(matched_font_face)) != 0)
|
||||
{
|
||||
log_verbose("FontConfig provided substitute font %s -- disregarding.", matched_font_face);
|
||||
is_substitute = true;
|
||||
}
|
||||
|
||||
FcChar8* filename = nullptr;
|
||||
if (!is_substitute && FcPatternGetString(match, FC_FILE, 0, &filename) == FcResultMatch)
|
||||
{
|
||||
found = true;
|
||||
safe_strcpy(buffer, reinterpret_cast<utf8*>(filename), size);
|
||||
log_verbose("FontConfig provided font %s", filename);
|
||||
}
|
||||
|
||||
FcPatternDestroy(match);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_warning("Failed to find required font.");
|
||||
}
|
||||
|
||||
FcPatternDestroy(pat);
|
||||
FcConfigDestroy(config);
|
||||
FcFini();
|
||||
return found;
|
||||
}
|
||||
# endif // NO_TTF
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,14 @@ namespace Platform
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
# ifndef NO_TTF
|
||||
std::string GetFontPath(const TTFFontDescriptor& font)
|
||||
{
|
||||
STUB();
|
||||
return "";
|
||||
}
|
||||
# endif
|
||||
} // namespace Platform
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
// for PATH_MAX
|
||||
# include <linux/limits.h>
|
||||
# endif // __linux__
|
||||
# ifndef NO_TTF
|
||||
# include <fontconfig/fontconfig.h>
|
||||
# endif // NO_TTF
|
||||
|
||||
# include "../OpenRCT2.h"
|
||||
# include "../core/Path.hpp"
|
||||
# include "../localisation/Language.h"
|
||||
@@ -310,6 +314,63 @@ namespace Platform
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GetFontPath(const TTFFontDescriptor& font)
|
||||
{
|
||||
log_verbose("Looking for font %s with FontConfig.", font.font_name);
|
||||
FcConfig* config = FcInitLoadConfigAndFonts();
|
||||
if (!config)
|
||||
{
|
||||
log_error("Failed to initialize FontConfig library");
|
||||
FcFini();
|
||||
return "";
|
||||
}
|
||||
|
||||
FcPattern* pat = FcNameParse(reinterpret_cast<const FcChar8*>(font.font_name));
|
||||
|
||||
FcConfigSubstitute(config, pat, FcMatchPattern);
|
||||
FcDefaultSubstitute(pat);
|
||||
|
||||
std::string path = "";
|
||||
FcResult result = FcResultNoMatch;
|
||||
FcPattern* match = FcFontMatch(config, pat, &result);
|
||||
|
||||
if (match)
|
||||
{
|
||||
bool is_substitute = false;
|
||||
|
||||
// FontConfig implicitly falls back to any default font it is configured to handle.
|
||||
// In our implementation, this cannot account for supported character sets, leading
|
||||
// to unrendered characters (tofu) when trying to render e.g. CJK characters using a
|
||||
// Western (sans-)serif font. We therefore ignore substitutions FontConfig provides,
|
||||
// and instead rely on exact matches on the fonts predefined for each font family.
|
||||
FcChar8* matched_font_face = nullptr;
|
||||
if (FcPatternGetString(match, FC_FULLNAME, 0, &matched_font_face) == FcResultMatch
|
||||
&& strcmp(font.font_name, reinterpret_cast<const char*>(matched_font_face)) != 0)
|
||||
{
|
||||
log_verbose("FontConfig provided substitute font %s -- disregarding.", matched_font_face);
|
||||
is_substitute = true;
|
||||
}
|
||||
|
||||
FcChar8* filename = nullptr;
|
||||
if (!is_substitute && FcPatternGetString(match, FC_FILE, 0, &filename) == FcResultMatch)
|
||||
{
|
||||
path = reinterpret_cast<utf8*>(filename);
|
||||
log_verbose("FontConfig provided font %s", filename);
|
||||
}
|
||||
|
||||
FcPatternDestroy(match);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_warning("Failed to find required font.");
|
||||
}
|
||||
|
||||
FcPatternDestroy(pat);
|
||||
FcConfigDestroy(config);
|
||||
FcFini();
|
||||
return path;
|
||||
}
|
||||
} // namespace Platform
|
||||
|
||||
#endif
|
||||
|
||||
@@ -852,6 +852,26 @@ namespace Platform
|
||||
RegCloseKey(hKey);
|
||||
return outPath;
|
||||
}
|
||||
|
||||
std::string GetFontPath(const TTFFontDescriptor& font)
|
||||
{
|
||||
# if !defined(__MINGW32__) && ((NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING))
|
||||
wchar_t* fontFolder;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Fonts, 0, nullptr, &fontFolder)))
|
||||
{
|
||||
// Convert wchar to utf8, then copy the font folder path to the buffer.
|
||||
auto outPathTemp = String::ToUtf8(fontFolder);
|
||||
CoTaskMemFree(fontFolder);
|
||||
|
||||
return Path::Combine(outPathTemp, font.filename);
|
||||
}
|
||||
|
||||
return "";
|
||||
# else
|
||||
log_warning("Compatibility hack: falling back to C:\\Windows\\Fonts");
|
||||
return Path::Combine("C:\\Windows\\Fonts\\", font.filename);
|
||||
# endif
|
||||
}
|
||||
} // namespace Platform
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
# undef interface
|
||||
# undef abstract
|
||||
|
||||
# include <CoreText/CoreText.h>
|
||||
# include <Foundation/Foundation.h>
|
||||
# include <mach-o/dyld.h>
|
||||
# include <pwd.h>
|
||||
@@ -250,6 +251,25 @@ namespace Platform
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GetFontPath(const TTFFontDescriptor& font)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize(
|
||||
static_cast<CFStringRef>([NSString stringWithUTF8String:font.font_name]), 0.0);
|
||||
CFURLRef url = static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute));
|
||||
if (url)
|
||||
{
|
||||
NSString* fontPath = [NSString stringWithString:[static_cast<NSURL*>(CFBridgingRelease(url)) path]];
|
||||
return fontPath.UTF8String;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,6 +64,9 @@ namespace Platform
|
||||
std::string GetEnvironmentPath(const char* name);
|
||||
std::string GetHomePath();
|
||||
#endif
|
||||
#ifndef NO_TTF
|
||||
std::string GetFontPath(const TTFFontDescriptor& font);
|
||||
#endif // NO_TTF
|
||||
|
||||
std::string FormatShortDate(std::time_t timestamp);
|
||||
std::string FormatTime(std::time_t timestamp);
|
||||
|
||||
@@ -96,8 +96,6 @@ int32_t platform_get_drives()
|
||||
return GetLogicalDrives();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string platform_get_rct1_steam_dir()
|
||||
{
|
||||
return "Rollercoaster Tycoon Deluxe";
|
||||
@@ -128,35 +126,6 @@ time_t platform_file_get_modified_time(const utf8* path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
# ifndef NO_TTF
|
||||
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
|
||||
{
|
||||
# if !defined(__MINGW32__) \
|
||||
&& ((NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING))
|
||||
wchar_t* fontFolder;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Fonts, 0, nullptr, &fontFolder)))
|
||||
{
|
||||
// Convert wchar to utf8, then copy the font folder path to the buffer.
|
||||
auto outPathTemp = String::ToUtf8(fontFolder);
|
||||
safe_strcpy(buffer, outPathTemp.c_str(), size);
|
||||
|
||||
CoTaskMemFree(fontFolder);
|
||||
|
||||
// Append the requested font's file name.
|
||||
safe_strcat_path(buffer, font->filename, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
# else
|
||||
log_warning("Compatibility hack: falling back to C:\\Windows\\Fonts");
|
||||
safe_strcpy(buffer, "C:\\Windows\\Fonts\\", size);
|
||||
safe_strcat_path(buffer, font->filename, size);
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
# endif // NO_TTF
|
||||
|
||||
std::string platform_get_absolute_path(const utf8* relativePath, const utf8* basePath)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
@@ -24,26 +24,4 @@
|
||||
# include <mach-o/dyld.h>
|
||||
# include <pwd.h>
|
||||
|
||||
# ifndef NO_TTF
|
||||
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize(
|
||||
static_cast<CFStringRef>([NSString stringWithUTF8String:font->font_name]), 0.0);
|
||||
CFURLRef url = static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute));
|
||||
if (url)
|
||||
{
|
||||
NSString* fontPath = [NSString stringWithString:[static_cast<NSURL*>(CFBridgingRelease(url)) path]];
|
||||
safe_strcpy(buffer, fontPath.UTF8String, size);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif // NO_TTF
|
||||
|
||||
#endif
|
||||
|
||||
@@ -101,10 +101,6 @@ utf8* platform_open_directory_browser(const utf8* title);
|
||||
std::string platform_get_rct1_steam_dir();
|
||||
std::string platform_get_rct2_steam_dir();
|
||||
|
||||
#ifndef NO_TTF
|
||||
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size);
|
||||
#endif // NO_TTF
|
||||
|
||||
datetime64 platform_get_datetime_now_utc();
|
||||
|
||||
float platform_get_default_scale();
|
||||
|
||||
Reference in New Issue
Block a user