LibGfx: Add API for loading more directories into Gfx::FontDatabase

Also make the font discovery algorithm search subdirectories as well.
This will be used by Ladybird to discover more fonts on non-Serenity
systems. :^)
This commit is contained in:
Andreas Kling 2022-09-08 12:30:25 +02:00
parent 5c2e3d1637
commit 3dc82d2fa5
Notes: sideshowbarker 2024-07-17 07:21:23 +09:00
2 changed files with 49 additions and 27 deletions

View file

@ -6,8 +6,10 @@
#include <AK/FlyString.h>
#include <AK/NonnullRefPtrVector.h>
#include <AK/Queue.h>
#include <AK/QuickSort.h>
#include <LibCore/DirIterator.h>
#include <LibCore/File.h>
#include <LibGfx/Font/Font.h>
#include <LibGfx/Font/FontDatabase.h>
#include <LibGfx/Font/TrueType/Font.h>
@ -120,41 +122,57 @@ struct FontDatabase::Private {
Vector<RefPtr<Typeface>> typefaces;
};
FontDatabase::FontDatabase()
: m_private(make<Private>())
void FontDatabase::load_all_fonts_from_path(String const& root)
{
Core::DirIterator dir_iterator(s_default_fonts_lookup_path, Core::DirIterator::SkipDots);
if (dir_iterator.has_error()) {
warnln("DirIterator: {}", dir_iterator.error_string());
exit(1);
}
while (dir_iterator.has_next()) {
auto path = dir_iterator.next_full_path();
Queue<String> path_queue;
path_queue.enqueue(root);
if (path.ends_with(".font"sv)) {
if (auto font_or_error = Gfx::BitmapFont::try_load_from_file(path); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
m_private->full_name_to_font_map.set(font->qualified_name(), *font);
auto typeface = get_or_create_typeface(font->family(), font->variant());
typeface->add_bitmap_font(font);
while (!path_queue.is_empty()) {
auto current_directory = path_queue.dequeue();
Core::DirIterator dir_iterator(current_directory, Core::DirIterator::SkipParentAndBaseDir);
if (dir_iterator.has_error()) {
dbgln("FontDatabase::load_fonts: {}", dir_iterator.error_string());
continue;
}
while (dir_iterator.has_next()) {
auto path = dir_iterator.next_full_path();
if (Core::File::is_directory(path)) {
path_queue.enqueue(path);
continue;
}
} else if (path.ends_with(".ttf"sv)) {
// FIXME: What about .otf
if (auto font_or_error = TTF::Font::try_load_from_file(path); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
auto typeface = get_or_create_typeface(font->family(), font->variant());
typeface->set_vector_font(move(font));
}
} else if (path.ends_with(".woff"sv)) {
if (auto font_or_error = WOFF::Font::try_load_from_file(path); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
auto typeface = get_or_create_typeface(font->family(), font->variant());
typeface->set_vector_font(move(font));
if (path.ends_with(".font"sv)) {
if (auto font_or_error = Gfx::BitmapFont::try_load_from_file(path); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
m_private->full_name_to_font_map.set(font->qualified_name(), *font);
auto typeface = get_or_create_typeface(font->family(), font->variant());
typeface->add_bitmap_font(font);
}
} else if (path.ends_with(".ttf"sv)) {
// FIXME: What about .otf
if (auto font_or_error = TTF::Font::try_load_from_file(path); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
auto typeface = get_or_create_typeface(font->family(), font->variant());
typeface->set_vector_font(move(font));
}
} else if (path.ends_with(".woff"sv)) {
if (auto font_or_error = WOFF::Font::try_load_from_file(path); !font_or_error.is_error()) {
auto font = font_or_error.release_value();
auto typeface = get_or_create_typeface(font->family(), font->variant());
typeface->set_vector_font(move(font));
}
}
}
}
}
FontDatabase::FontDatabase()
: m_private(make<Private>())
{
load_all_fonts_from_path(s_default_fonts_lookup_path);
}
void FontDatabase::for_each_font(Function<void(Gfx::Font const&)> callback)
{
Vector<RefPtr<Gfx::Font>> fonts;

View file

@ -56,10 +56,14 @@ public:
void for_each_typeface(Function<void(Typeface const&)>);
void load_all_fonts_from_path(String const&);
private:
FontDatabase();
~FontDatabase() = default;
void load_fonts();
RefPtr<Typeface> get_or_create_typeface(String const& family, String const& variant);
struct Private;