Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fontconfig: Make init and teardown more robust. #1793

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
146 changes: 62 additions & 84 deletions rts/Rendering/Fonts/CFontTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,56 +89,23 @@ class FtLibraryHandler {
: config(nullptr)
, lib(nullptr)
{
{
const FT_Error error = FT_Init_FreeType(&lib);

FT_Int version[3];
FT_Library_Version(lib, &version[0], &version[1], &version[2]);
const FT_Error error = FT_Init_FreeType(&lib);

std::string msg = fmt::sprintf("%s::FreeTypeInit (version %d.%d.%d)", __func__, version[0], version[1], version[2]);
std::string err = fmt::sprintf("[%s] FT_Init_FreeType failure \"%s\"", __func__, GetFTError(error));
FT_Int version[3];
FT_Library_Version(lib, &version[0], &version[1], &version[2]);

if (error != 0)
throw std::runtime_error(err);
}

#ifdef USE_FONTCONFIG
if (!UseFontConfig())
return;

{
std::string msg = fmt::sprintf("%s::FontConfigInit (version %d.%d.%d)", __func__, FC_MAJOR, FC_MINOR, FC_REVISION);
ScopedOnceTimer timer(msg);
ZoneScopedNC("FtLibraryHandler::FontConfigInit", tracy::Color::Purple);

try
{
FcInit();
} catch (const std::exception& e) {
LOG("FcInit() runtime error: \"%s\"", e.what());
config = nullptr;
return;
}

FcConfigEnableHome(FcFalse);
config = FcInitLoadConfigAndFonts();
if (!config)
return;
std::string msg = fmt::sprintf("%s::FreeTypeInit (version %d.%d.%d)", __func__, version[0], version[1], version[2]);
std::string err = fmt::sprintf("[%s] FT_Init_FreeType failure \"%s\"", __func__, GetFTError(error));
saurtron marked this conversation as resolved.
Show resolved Hide resolved

static constexpr const char* cacheDirFmt = R"(<fontconfig><cachedir>fontcache</cachedir></fontconfig>)";
if (!FcConfigParseAndLoadFromMemory(config, reinterpret_cast<const FcChar8*>(cacheDirFmt), FcTrue)) {
FcConfigDestroy(config);
config = nullptr;
}
}
#endif
if (error != 0)
throw std::runtime_error(err);
}

~FtLibraryHandler() {
FT_Done_FreeType(lib);

#ifdef USE_FONTCONFIG
if (!UseFontConfig())
if (!CanUseFontConfig())
return;

FcConfigDestroy(config);
Expand All @@ -147,22 +114,8 @@ class FtLibraryHandler {
#endif
}

// reduced set of fonts
// not called if FcInit() fails
static bool CheckGenFontConfigFast() {
FcConfigAppFontClear(GetFCConfig());
if (!FcConfigAppFontAddDir(GetFCConfig(), reinterpret_cast<const FcChar8*>("fonts")))
return false;

if (!FtLibraryHandler::CheckFontConfig()) {
return FcConfigBuildFonts(GetFCConfig());
}

return true;
}

static bool CheckGenFontConfigFull(bool console) {
#ifndef HEADLESS
bool InitFontconfig(bool console) {
#ifdef USE_FONTCONFIG
auto LOG_MSG = [console](const std::string& fmt, bool isError, auto&&... args) {
if (console) {
std::string fmtNL = fmt + "\n";
Expand All @@ -178,15 +131,51 @@ class FtLibraryHandler {
}
};

if (!FtLibraryHandler::CanUseFontConfig()) {
LOG_MSG("[%s] Fontconfig(version %d.%d.%d) failed to initialize", true, __func__, FC_MAJOR, FC_MINOR, FC_REVISION);
if (!UseFontConfig())
return false;
}

FcConfigAppFontClear(GetFCConfig());
FcConfigAppFontAddDir(GetFCConfig(), reinterpret_cast<const FcChar8*>("fonts"));

{
std::string msg = fmt::sprintf("%s::FontConfigInit (version %d.%d.%d)", __func__, FC_MAJOR, FC_MINOR, FC_REVISION);
ScopedOnceTimer timer(msg);
ZoneScopedNC("FtLibraryHandler::FontConfigInit", tracy::Color::Purple);

FcBool res;
std::string errprefix = fmt::sprintf("[%s] Fontconfig(version %d.%d.%d) failed to initialize", __func__, FC_MAJOR, FC_MINOR, FC_REVISION);

// library init
res = FcInit();
if (!res) {
LOG_MSG("%s failed to initialize", true, errprefix);
return false;
}

// init configuration
FcConfigEnableHome(FcFalse);
config = FcInitLoadConfigAndFonts();
if (!config) {
LOG_MSG(errprefix.c_str(), true);
FcFini();
return false;
}

// add local cache
static constexpr const char* cacheDirFmt = R"(<fontconfig><cachedir>fontcache</cachedir></fontconfig>)";
res = FcConfigParseAndLoadFromMemory(config, reinterpret_cast<const FcChar8*>(cacheDirFmt), FcTrue);
if (!res) {
LOG_MSG("%s cache", true, errprefix);
InitFailed();
return false;
}

// init app fonts dir
res = FcConfigAppFontAddDir(GetFCConfig(), reinterpret_cast<const FcChar8*>("fonts"));
if (!res) {
LOG_MSG("%s font dir", true, errprefix);
InitFailed();
return false;
}

// print cache dirs
auto dirs = FcConfigGetCacheDirs(GetFCConfig());
FcStrListFirst(dirs);
for (FcChar8* dir = FcStrListNext(dirs); dir != nullptr; dir = FcStrListNext(dirs)) {
Expand All @@ -195,19 +184,18 @@ class FtLibraryHandler {
FcStrListDone(dirs);
}

if (FtLibraryHandler::CheckFontConfig()) {
LOG_MSG("[%s] fontconfig up to date", false, __func__);
return true;
}

LOG_MSG("[%s] creating fontconfig", false, __func__);

return FcConfigBuildFonts(GetFCConfig());
#endif
#endif // USE_FONTCONFIG

return true;
}

void InitFailed() {
FcConfigDestroy(config);
FcFini();
config = nullptr;
}
static bool InitSingletonFontconfig(bool console) { return singleton->InitFontconfig(console); }

static bool UseFontConfig() { return (configHandler == nullptr || configHandler->GetBool("UseFontConfigLib")); }

#ifdef USE_FONTCONFIG
Expand Down Expand Up @@ -252,21 +240,11 @@ void FtLibraryHandlerProxy::InitFtLibrary()
#endif
}

bool FtLibraryHandlerProxy::CheckGenFontConfigFast()
{
RECOIL_DETAILED_TRACY_ZONE;
#ifndef HEADLESS
return FtLibraryHandler::CheckGenFontConfigFast();
#else
return false;
#endif
}

bool FtLibraryHandlerProxy::CheckGenFontConfigFull(bool console)
bool FtLibraryHandlerProxy::InitFontconfig(bool console)
{
RECOIL_DETAILED_TRACY_ZONE;
#ifndef HEADLESS
return FtLibraryHandler::CheckGenFontConfigFull(console);
return FtLibraryHandler::InitSingletonFontconfig(console);
#else
return false;
#endif
Expand Down
3 changes: 1 addition & 2 deletions rts/Rendering/Fonts/CFontTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ class CBitmap;
class FtLibraryHandlerProxy {
public:
static void InitFtLibrary();
static bool CheckGenFontConfigFast();
static bool CheckGenFontConfigFull(bool console);
static bool InitFontconfig(bool console);
};


Expand Down
6 changes: 3 additions & 3 deletions rts/System/SpringApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,9 @@ bool SpringApp::InitPlatformLibs()
bool SpringApp::InitFonts()
{
FtLibraryHandlerProxy::InitFtLibrary();
FtLibraryHandlerProxy::CheckGenFontConfigFast();
FtLibraryHandlerProxy::InitFontconfig(false);
CFontTexture::InitFonts();
return CglFont::LoadConfigFonts() && FtLibraryHandlerProxy::CheckGenFontConfigFull(false);
return CglFont::LoadConfigFonts();
/*
using namespace std::chrono_literals;
auto future = std::async(std::launch::async, []() {
Expand Down Expand Up @@ -478,7 +478,7 @@ void SpringApp::ParseCmdLine(int argc, char* argv[])
spring_time::setstarttime(spring_time::gettime(true));
}
FtLibraryHandlerProxy::InitFtLibrary();
if (FtLibraryHandlerProxy::CheckGenFontConfigFull(true)) {
if (FtLibraryHandlerProxy::InitFontconfig(true)) {
printf("[FtLibraryHandler::GenFontConfig] is succesfull\n");
exit(spring::EXIT_CODE_SUCCESS);
}
Expand Down