1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-08 05:27:14 +09:00
ladybird/Userland/Libraries/LibGfx/Font/FontDatabase.cpp
Aliaksandr Kalenik a9d5a99568 LibGfx+LibWeb: Replace remaining OpenType implementation with Skia
This change should move us forward toward emoji support, as we are no
longer limited by our own OpenType implementation, which was failing
to parse the TrueType Collection format used to store emoji fonts
(at least on macOS).
2024-09-05 19:21:52 +02:00

103 lines
3.3 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/DeprecatedFlyString.h>
#include <AK/FlyString.h>
#include <AK/LexicalPath.h>
#include <AK/Queue.h>
#include <LibCore/Resource.h>
#include <LibGfx/Font/Font.h>
#include <LibGfx/Font/FontDatabase.h>
#include <LibGfx/Font/ScaledFont.h>
#include <LibGfx/Font/WOFF/Loader.h>
namespace Gfx {
FontDatabase& FontDatabase::the()
{
static FontDatabase s_the;
return s_the;
}
struct FontDatabase::Private {
bool force_fontconfig { false };
HashMap<FlyString, Vector<NonnullRefPtr<Typeface>>, AK::ASCIICaseInsensitiveFlyStringTraits> typeface_by_family;
};
void FontDatabase::set_force_fontconfig(bool force_fontconfig)
{
m_private->force_fontconfig = force_fontconfig;
}
bool FontDatabase::should_force_fontconfig() const
{
return m_private->force_fontconfig;
}
void FontDatabase::load_all_fonts_from_uri(StringView uri)
{
auto root_or_error = Core::Resource::load_from_uri(uri);
if (root_or_error.is_error()) {
if (root_or_error.error().is_errno() && root_or_error.error().code() == ENOENT) {
return;
}
dbgln("FontDatabase::load_all_fonts_from_uri('{}'): {}", uri, root_or_error.error());
return;
}
auto root = root_or_error.release_value();
root->for_each_descendant_file([this](Core::Resource const& resource) -> IterationDecision {
auto uri = resource.uri();
auto path = LexicalPath(uri.bytes_as_string_view());
if (path.has_extension(".ttf"sv)) {
// FIXME: What about .otf
if (auto font_or_error = Typeface::try_load_from_resource(resource); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
auto& family = m_private->typeface_by_family.ensure(font->family(), [] {
return Vector<NonnullRefPtr<Typeface>> {};
});
family.append(font);
}
} else if (path.has_extension(".woff"sv)) {
if (auto font_or_error = WOFF::try_load_from_resource(resource); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
auto& family = m_private->typeface_by_family.ensure(font->family(), [] {
return Vector<NonnullRefPtr<Typeface>> {};
});
family.append(font);
}
}
return IterationDecision::Continue;
});
}
FontDatabase::FontDatabase()
: m_private(make<Private>())
{
}
RefPtr<Gfx::Font> FontDatabase::get(FlyString const& family, float point_size, unsigned weight, unsigned width, unsigned slope)
{
auto it = m_private->typeface_by_family.find(family);
if (it == m_private->typeface_by_family.end())
return nullptr;
for (auto const& typeface : it->value) {
if (typeface->weight() == weight && typeface->width() == width && typeface->slope() == slope)
return typeface->scaled_font(point_size);
}
return nullptr;
}
void FontDatabase::for_each_typeface_with_family_name(FlyString const& family_name, Function<void(Typeface const&)> callback)
{
auto it = m_private->typeface_by_family.find(family_name);
if (it == m_private->typeface_by_family.end())
return;
for (auto const& typeface : it->value)
callback(*typeface);
}
}