diff --git a/libc3/window/cairo/cairo_font.c b/libc3/window/cairo/cairo_font.c
new file mode 100644
index 0000000..520d1e6
--- /dev/null
+++ b/libc3/window/cairo/cairo_font.c
@@ -0,0 +1,62 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <assert.h>
+#include <err.h>
+#include <libc3/c3.h>
+#include "cairo_font.h"
+
+static FT_Library *g_cairo_font_ft = NULL;
+
+static FT_Library * cairo_font_ft (void);
+
+void cairo_font_clean (s_cairo_font *font)
+{
+ assert(font);
+ cairo_font_face_destroy(font->cairo_font_face);
+ FT_Done_Face(font->ft_face);
+ str_clean(&font->path);
+}
+
+static FT_Library * cairo_font_ft (void)
+{
+ if (! g_cairo_font_ft) {
+ if (! (g_cairo_font_ft = malloc(sizeof(FT_Library)))) {
+ warn("cairo_font_ft");
+ return NULL;
+ }
+ if (FT_Init_FreeType(g_cairo_font_ft)) {
+ warnx("cairo_font_ft: error initializing FreeType");
+ free(g_cairo_font_ft);
+ g_cairo_font_ft = NULL;
+ return NULL;
+ }
+ }
+ return g_cairo_font_ft;
+}
+
+s_cairo_font * cairo_font_init (s_cairo_font *font, s_str *path)
+{
+ FT_Library *ft;
+ assert(font);
+ assert(path);
+ if (! (ft = cairo_font_ft()))
+ return NULL;
+ str_init_copy(&font->path, path);
+ if (FT_New_Face(*ft, path->ptr.ps8, 0, &font->ft_face)) {
+ warnx("cairo_font_init(%s): Error loading font", path->ptr.ps8);
+ return NULL;
+ }
+ font->cairo_font_face = cairo_ft_font_face_create_for_ft_face
+ (font->ft_face, 0);
+ return font;
+}
diff --git a/libc3/window/cairo/cairo_font.h b/libc3/window/cairo/cairo_font.h
new file mode 100644
index 0000000..a1af2c2
--- /dev/null
+++ b/libc3/window/cairo/cairo_font.h
@@ -0,0 +1,25 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef LIBC3_WINDOW_CAIRO_CAIRO_FONT_H
+#define LIBC3_WINDOW_CAIRO_CAIRO_FONT_H
+
+#include <assert.h>
+#include <err.h>
+#include "types.h"
+
+/* Stack-allocation compatible functions, call cairo_font_clean after
+ use. */
+void cairo_font_clean (s_cairo_font *font);
+s_cairo_font * cairo_font_init (s_cairo_font *font, s_str *path);
+
+#endif /* LIBC3_WINDOW_CAIRO_CAIRO_FONT_H */
diff --git a/libc3/window/cairo/configure b/libc3/window/cairo/configure
index 1014bfb..32af4a8 100755
--- a/libc3/window/cairo/configure
+++ b/libc3/window/cairo/configure
@@ -43,6 +43,7 @@ LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
pkg_config cairo
+pkg_config freetype2
pkg_config libbsd-overlay
pkg_config xkbcommon
config_lib_have COCOA -framework Cocoa
diff --git a/libc3/window/cairo/sources.mk b/libc3/window/cairo/sources.mk
index 8ca2a45..f6d4a27 100644
--- a/libc3/window/cairo/sources.mk
+++ b/libc3/window/cairo/sources.mk
@@ -1,11 +1,13 @@
# sources.mk generated by update_sources
HEADERS = \
+ cairo_font.h \
cairo_png.h \
cairo_sprite.h \
types.h \
window_cairo.h \
SOURCES = \
+ cairo_font.c \
cairo_png.c \
cairo_sprite.c \
window_cairo.c \
diff --git a/libc3/window/cairo/sources.sh b/libc3/window/cairo/sources.sh
index baa3a7d..8a467a8 100644
--- a/libc3/window/cairo/sources.sh
+++ b/libc3/window/cairo/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS='cairo_png.h cairo_sprite.h types.h window_cairo.h '
-SOURCES='cairo_png.c cairo_sprite.c window_cairo.c '
+HEADERS='cairo_font.h cairo_png.h cairo_sprite.h types.h window_cairo.h '
+SOURCES='cairo_font.c cairo_png.c cairo_sprite.c window_cairo.c '
diff --git a/libc3/window/cairo/types.h b/libc3/window/cairo/types.h
index c4a5a44..20d9b19 100644
--- a/libc3/window/cairo/types.h
+++ b/libc3/window/cairo/types.h
@@ -19,9 +19,13 @@
#define LIBC3_WINDOW_CAIRO_TYPES_H
#include <cairo.h>
+#include <cairo-ft.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
#include <libc3/types.h>
#include "../types.h"
+typedef struct cairo_font s_cairo_font;
typedef struct cairo_sprite s_cairo_sprite;
typedef struct rgb s_rgb;
typedef struct rgba s_rgba;
@@ -56,6 +60,12 @@ typedef bool (*f_window_cairo_sequence_render) (s_sequence *seq,
s_window_cairo *window,
cairo_t *cr);
+struct cairo_font {
+ cairo_font_face_t *cairo_font_face;
+ FT_Face ft_face;
+ s_str path;
+};
+
struct cairo_sprite {
uw surface_w;
uw surface_h;