瀏覽代碼

LibGUI: Add a GFontDatabase class that lets you enumerate fonts and more.

"More" in this case being also giving you the ability to load a font by name.
Use this as backend for Terminal's font menu. :^)
Andreas Kling 6 年之前
父節點
當前提交
d6326d6c2e
共有 4 個文件被更改,包括 79 次插入8 次删除
  1. 7 8
      Applications/Terminal/main.cpp
  2. 50 0
      LibGUI/GFontDatabase.cpp
  3. 21 0
      LibGUI/GFontDatabase.h
  4. 1 0
      LibGUI/Makefile

+ 7 - 8
Applications/Terminal/main.cpp

@@ -15,6 +15,7 @@
 #include <LibGUI/GWindow.h>
 #include <LibGUI/GMenuBar.h>
 #include <LibGUI/GAction.h>
+#include <LibGUI/GFontDatabase.h>
 
 static void make_shell(int ptm_fd)
 {
@@ -104,14 +105,12 @@ int main(int argc, char** argv)
     menubar->add_menu(move(app_menu));
 
     auto font_menu = make<GMenu>("Font");
-    auto handle_font_selection = [&terminal] (const GAction& action) {
-        terminal.set_font(Font::load_from_file(action.custom_data()));
-        terminal.force_repaint();
-    };
-    font_menu->add_action(make<GAction>("Liza Thin", "/res/fonts/LizaThin8x10.font", move(handle_font_selection)));
-    font_menu->add_action(make<GAction>("Liza Regular", "/res/fonts/LizaRegular8x10.font", move(handle_font_selection)));
-    font_menu->add_action(make<GAction>("Liza Bold", "/res/fonts/LizaBold8x10.font", move(handle_font_selection)));
-
+    GFontDatabase::the().for_each_font([&] (const String& font_name) {
+        font_menu->add_action(make<GAction>(font_name, [&terminal] (const GAction& action) {
+            terminal.set_font(GFontDatabase::the().get_by_name(action.text()));
+            terminal.force_repaint();
+        }));
+    });
     menubar->add_menu(move(font_menu));
 
     auto help_menu = make<GMenu>("Help");

+ 50 - 0
LibGUI/GFontDatabase.cpp

@@ -0,0 +1,50 @@
+#include <LibGUI/GFontDatabase.h>
+#include <SharedGraphics/Font.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static GFontDatabase* s_the;
+
+GFontDatabase& GFontDatabase::the()
+{
+    if (!s_the)
+        s_the = new GFontDatabase;
+    return *s_the;
+}
+
+GFontDatabase::GFontDatabase()
+{
+    DIR* dirp = opendir("/res/fonts");
+    if (!dirp) {
+        perror("opendir");
+        exit(1);
+    }
+    while (auto* de = readdir(dirp)) {
+        if (de->d_name[0] == '.')
+            continue;
+        auto path = String::format("/res/fonts/%s", de->d_name);
+        if (auto font = Font::load_from_file(path))
+            m_name_to_path.set(font->name(), path);
+    }
+    closedir(dirp);
+}
+
+GFontDatabase::~GFontDatabase()
+{
+}
+
+void GFontDatabase::for_each_font(Function<void(const String&)> callback)
+{
+    for (auto& it : m_name_to_path) {
+        callback(it.key);
+    }
+}
+
+RetainPtr<Font> GFontDatabase::get_by_name(const String& name)
+{
+    auto it = m_name_to_path.find(name);
+    if (it == m_name_to_path.end())
+        return nullptr;
+    return Font::load_from_file((*it).value);
+}

+ 21 - 0
LibGUI/GFontDatabase.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include <AK/AKString.h>
+#include <AK/HashMap.h>
+#include <AK/Function.h>
+
+class Font;
+
+class GFontDatabase {
+public:
+    static GFontDatabase& the();
+
+    RetainPtr<Font> get_by_name(const String&);
+    void for_each_font(Function<void(const String&)>);
+
+private:
+    GFontDatabase();
+    ~GFontDatabase();
+
+    HashMap<String, String> m_name_to_path;
+};

+ 1 - 0
LibGUI/Makefile

@@ -26,6 +26,7 @@ LIBGUI_OBJS = \
     GMenuItem.o \
     GApplication.o \
     GAction.o \
+    GFontDatabase.o \
     GWindow.o
 
 OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)