LibGfx: Rely on fontconfig(if enabled) for font directory resolution

this commit also introduces GlobalFontConfig class that is now
responsible for fontconfig initialization. it seems sane, even thought
FcInit's docs state that if the default configuration has already been
loaded, this routine does nothing.
This commit is contained in:
blukai 2025-05-21 02:55:15 +02:00 committed by Andrew Kaster
commit e356a4bd01
Notes: github-actions[bot] 2025-05-26 18:15:33 +00:00
5 changed files with 86 additions and 10 deletions

View file

@ -72,6 +72,10 @@ if (HAS_VULKAN)
list(APPEND SOURCES VulkanContext.cpp)
endif()
if (HAS_FONTCONFIG)
list(APPEND SOURCES Font/GlobalFontConfig.cpp)
endif()
serenity_lib(LibGfx gfx)
target_link_libraries(LibGfx PRIVATE LibCompress LibCore LibCrypto LibFileSystem LibRIFF LibTextCodec LibIPC LibUnicode LibURL)

View file

@ -13,6 +13,10 @@
# include <FindDirectory.h>
#endif
#ifdef USE_FONTCONFIG
# include <LibGfx/Font/GlobalFontConfig.h>
#endif
namespace Gfx {
// Key function for SystemFontProvider to emit the vtable here
@ -51,7 +55,16 @@ void FontDatabase::for_each_typeface_with_family_name(FlyString const& family_na
ErrorOr<Vector<String>> FontDatabase::font_directories()
{
#if defined(AK_OS_HAIKU)
#if defined(USE_FONTCONFIG)
Vector<String> paths;
FcConfig* config = Gfx::GlobalFontConfig::the().get();
FcStrList* dirs = FcConfigGetFontDirs(config);
while (FcChar8* dir = FcStrListNext(dirs)) {
char const* dir_cstring = reinterpret_cast<char const*>(dir);
paths.append(TRY(String::from_utf8(StringView { dir_cstring, strlen(dir_cstring) })));
}
return paths;
#elif defined(AK_OS_HAIKU)
Vector<String> paths_vector;
char** paths;
size_t paths_count;

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2025, blukai <init1@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Assertions.h>
#include <LibGfx/Font/GlobalFontConfig.h>
#include <fontconfig/fontconfig.h>
namespace Gfx {
GlobalFontConfig::GlobalFontConfig()
{
FcBool inited = FcInit();
VERIFY(inited);
m_config = FcConfigGetCurrent();
FcConfigReference(m_config);
}
GlobalFontConfig::~GlobalFontConfig()
{
FcConfigDestroy(m_config);
}
GlobalFontConfig& GlobalFontConfig::the()
{
static GlobalFontConfig s_the;
return s_the;
}
FcConfig* GlobalFontConfig::get()
{
return m_config;
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2025, blukai <init1@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <fontconfig/fontconfig.h>
namespace Gfx {
class GlobalFontConfig {
public:
static GlobalFontConfig& the();
FcConfig* get();
private:
GlobalFontConfig();
~GlobalFontConfig();
GlobalFontConfig(GlobalFontConfig const&) = delete;
GlobalFontConfig& operator=(GlobalFontConfig const&) = delete;
FcConfig* m_config;
};
}

View file

@ -16,7 +16,7 @@
#include <LibWebView/Plugins/FontPlugin.h>
#ifdef USE_FONTCONFIG
# include <fontconfig/fontconfig.h>
# include <LibGfx/Font/GlobalFontConfig.h>
#endif
namespace WebView {
@ -24,13 +24,6 @@ namespace WebView {
FontPlugin::FontPlugin(bool is_layout_test_mode, Gfx::SystemFontProvider* font_provider)
: m_is_layout_test_mode(is_layout_test_mode)
{
#ifdef USE_FONTCONFIG
{
auto fontconfig_initialized = FcInit();
VERIFY(fontconfig_initialized);
}
#endif
if (!font_provider)
font_provider = &static_cast<Gfx::PathFontProvider&>(Gfx::FontDatabase::the().install_system_font_provider(make<Gfx::PathFontProvider>()));
if (is<Gfx::PathFontProvider>(*font_provider)) {
@ -114,7 +107,7 @@ static Optional<String> query_fontconfig_for_generic_family(Web::Platform::Gener
VERIFY_NOT_REACHED();
}
auto* config = FcConfigGetCurrent();
auto* config = Gfx::GlobalFontConfig::the().get();
VERIFY(config);
FcPattern* pattern = FcNameParse(reinterpret_cast<FcChar8 const*>(pattern_string));