changeset 603:ed1d3244ed57

ui: start re-working delegates
author David Demelier <markand@malikania.fr>
date Thu, 10 Aug 2023 19:57:00 +0200
parents 7e168493f0bd
children dd80b59fffaf
files examples/example-font/example-font.c examples/example-label/example-label.c libmlk-example/mlk/example/trace-hud.c libmlk-rpg/mlk/rpg/message.c libmlk-ui/CMakeLists.txt libmlk-ui/mlk/ui/button.c libmlk-ui/mlk/ui/debug.c libmlk-ui/mlk/ui/gridmenu.c libmlk-ui/mlk/ui/label.c libmlk-ui/mlk/ui/label.h libmlk-ui/mlk/ui/notify.c libmlk-ui/mlk/ui/style.c libmlk-ui/mlk/ui/style.h libmlk-ui/mlk/ui/ui.c libmlk-ui/mlk/ui/ui.h
diffstat 15 files changed, 305 insertions(+), 130 deletions(-) [+]
line wrap: on
line diff
--- a/examples/example-font/example-font.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/examples/example-font/example-font.c	Thu Aug 10 19:57:00 2023 +0200
@@ -97,7 +97,7 @@
 {
 	(void)st;
 
-	struct mlk_font *font = mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	struct mlk_font *font = &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 	struct mlk_texture tex;
 
 	mlk_painter_set_color(MLK_EXAMPLE_BG);
--- a/examples/example-label/example-label.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/examples/example-label/example-label.c	Thu Aug 10 19:57:00 2023 +0200
@@ -31,29 +31,20 @@
 
 #include <mlk/ui/align.h>
 #include <mlk/ui/label.h>
+#include <mlk/ui/style.h>
 #include <mlk/ui/ui.h>
 
 #include <mlk/example/example.h>
 #include <mlk/example/glower.h>
 
-static struct mlk_label_style style = {
-	.color = 0x005162ff
-};
-
-/*
- * Add a glower effect to the main label in the middle.
- */
-static void main_update(struct mlk_label_delegate *, struct mlk_label *, unsigned int);
-
-static struct mlk_glower main_glower = {
+/* Custom delegate/style for glowing one. */
+static struct mlk_style style_glow;
+static struct mlk_label_delegate delegate_glow;
+static struct mlk_glower glower = {
 	.start  = 0xffce7fff,
 	.end    = 0xd58d6bff,
 	.delay  = 22
 };
-static struct mlk_label_delegate main_delegate = {
-	.update = main_update
-};
-static struct mlk_label_style main_style;
 
 static struct {
 	enum mlk_align align;
@@ -63,80 +54,89 @@
 		.align = MLK_ALIGN_CENTER,
 		.label = {
 			.text = "The world is Malikania.",
-			.style = &main_style,
-			.delegate = &main_delegate
+			.style = &style_glow,
+			.delegate = &delegate_glow
 		}
 	},
 	{
 		.align = MLK_ALIGN_TOP_LEFT,
 		.label = {
 			.text = "Top left",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_TOP,
 		.label = {
 			.text = "Top",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_TOP_RIGHT,
 		.label = {
 			.text = "Top right",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_RIGHT,
 		.label = {
 			.text = "Right",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_BOTTOM_RIGHT,
 		.label = {
 			.text = "Bottom right",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_BOTTOM,
 		.label = {
 			.text = "Bottom",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_BOTTOM_LEFT,
 		.label = {
 			.text = "Bottom left",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	},
 	{
 		.align = MLK_ALIGN_LEFT,
 		.label = {
 			.text = "Left",
-			.style = &style
+			.style = &mlk_style,
+			.delegate = &mlk_label_delegate
 		}
 	}
 };
 
 static struct mlk_label mouse_label = {
 	.text = "This one follows your mouse and is not aligned.",
-	.style = &style
+	.style = &mlk_style,
+	.delegate = &mlk_label_delegate
 };
 
 static void
-main_update(struct mlk_label_delegate *delegate, struct mlk_label *label, unsigned int ticks)
+delegate_glow_update(struct mlk_label_delegate *self, struct mlk_label *label, unsigned int ticks)
 {
-	(void)delegate;
+	(void)self;
 
-	mlk_glower_update(&main_glower, ticks);
-	label->style->color = main_glower.color;
+	mlk_glower_update(&glower, ticks);
+	label->style->text_color = glower.color;
 }
 
 static void
@@ -154,7 +154,15 @@
 		mlk_align(table[i].align, &l->x, &l->y, w, h, 0, 0, mlk_window.w, mlk_window.h);
 	}
 
-	mlk_glower_init(&main_glower);
+	mlk_glower_init(&glower);
+
+	/* Change default style. */
+	mlk_style.text_color = 0x005162ff;
+
+	/* Copy default label delegate and style and adapt. */
+	style_glow = mlk_style;
+	delegate_glow = mlk_label_delegate;
+	delegate_glow.update = delegate_glow_update;
 }
 
 static void
--- a/libmlk-example/mlk/example/trace-hud.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-example/mlk/example/trace-hud.c	Thu Aug 10 19:57:00 2023 +0200
@@ -90,7 +90,7 @@
 	struct mlk_font *font;
 	unsigned fh;
 
-	font = mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	font = &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 	fh = mlk_font_height(font);
 
 	for (int i = 0; i < LINES_MAX && data.lines[i][0]; ++i) {
--- a/libmlk-rpg/mlk/rpg/message.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-rpg/mlk/rpg/message.c	Thu Aug 10 19:57:00 2023 +0200
@@ -44,7 +44,7 @@
 	if (style->text_font)
 		return style->text_font;
 
-	return mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	return &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 }
 
 static unsigned int
--- a/libmlk-ui/CMakeLists.txt	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/CMakeLists.txt	Thu Aug 10 19:57:00 2023 +0200
@@ -28,6 +28,7 @@
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/gridmenu.c
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/label.c
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/notify.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/style.c
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/ui.c
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/ui_p.h
 )
@@ -42,6 +43,7 @@
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/gridmenu.h
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/label.h
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/notify.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/style.h
 	${libmlk-ui_SOURCE_DIR}/mlk/ui/ui.h
 )
 
--- a/libmlk-ui/mlk/ui/button.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/button.c	Thu Aug 10 19:57:00 2023 +0200
@@ -48,7 +48,7 @@
 	if (style->text_font)
 		return style->text_font;
 
-	return mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	return &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 }
 
 static void
--- a/libmlk-ui/mlk/ui/debug.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/debug.c	Thu Aug 10 19:57:00 2023 +0200
@@ -66,7 +66,7 @@
 	vsnprintf(line, sizeof (line), fmt, ap);
 
 	// TODO: add style support.
-	font = mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	font = &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 
 	if (mlk_font_render(font, &tex, line, MLK_UI_COLOR_DEBUG) < 0)
 		return;
--- a/libmlk-ui/mlk/ui/gridmenu.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/gridmenu.c	Thu Aug 10 19:57:00 2023 +0200
@@ -44,7 +44,7 @@
 	if (style && style->text_font)
 		return style->text_font;
 
-	return mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	return &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 }
 
 static struct index
--- a/libmlk-ui/mlk/ui/label.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/label.c	Thu Aug 10 19:57:00 2023 +0200
@@ -17,56 +17,34 @@
  */
 
 #include <assert.h>
-#include <string.h>
 
-#include <mlk/core/err.h>
 #include <mlk/core/font.h>
-#include <mlk/core/texture.h>
-#include <mlk/core/trace.h>
 
 #include "align.h"
 #include "label.h"
+#include "style.h"
 #include "ui.h"
-#include "ui_p.h"
-
-static inline struct mlk_font *
-style_font(const struct mlk_label *label)
-{
-	const struct mlk_label_style *style = MLK__STYLE(label, mlk_label_style);
-
-	if (style->font)
-		return style->font;
-
-	return mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
-}
 
 static int
-delegate_query(struct mlk_label_delegate *delegate, const struct mlk_label *label, unsigned int *w, unsigned *h)
+query(struct mlk_label_delegate *self,
+      const struct mlk_label *label,
+      unsigned int *w,
+      unsigned int *h)
 {
-	(void)delegate;
-
-	struct mlk_font *font;
-	int err;
+	(void)self;
 
-	font = style_font(label);
-
-	if ((err = mlk_font_query(font, label->text, w, h)) < 0)
-		return err;
-
-	return 0;
+	return mlk_font_query(label->style->text_font, label->text, w, h);
 }
 
 static void
-delegate_draw(struct mlk_label_delegate *delegate, const struct mlk_label *label)
+draw(struct mlk_label_delegate *self, const struct mlk_label *label)
 {
-	(void)delegate;
-
-	const struct mlk_label_style *style = MLK__STYLE(label, mlk_label_style);
+	(void)self;
 
 	mlk_ui_draw_text(
 		MLK_ALIGN_NONE,
-		style_font(label),
-		style->color,
+		label->style->text_font,
+		label->style->text_color,
 		label->text,
 		label->x,
 		label->y,
@@ -75,27 +53,32 @@
 	);
 }
 
-struct mlk_label_style mlk_label_style = {
-	.color  = MLK_UI_COLOR_TEXT
+struct mlk_label_delegate mlk_label_delegate = {
+	.query = query,
+	.draw = draw
 };
 
-struct mlk_label_delegate mlk_label_delegate = {
-	.query  = delegate_query,
-	.draw   = delegate_draw
-};
+void
+mlk_label_init(struct mlk_label *lbl,
+               struct mlk_style *st,
+               struct mlk_label_delegate *dt)
+{
+	assert(lbl);
 
-int
-mlk_label_ok(const struct mlk_label *label)
-{
-	return label && label->text && strlen(label->text) > 0;
+	lbl->x = 0;
+	lbl->y = 0;
+	lbl->text = "";
+	lbl->style = st ? st : &mlk_style;
+	lbl->delegate = dt ? dt : &mlk_label_delegate;
 }
 
 int
-mlk_label_query(const struct mlk_label *label, unsigned int *w, unsigned int *h)
+mlk_label_query(const struct mlk_label *lbl, unsigned int *w, unsigned int *h)
 {
-	assert(mlk_label_ok(label));
+	assert(lbl);
 
-	MLK__DELEGATE_INVOKE_RET(label->delegate, mlk_label_delegate, query, label, w, h);
+	if (lbl->delegate->query)
+		return lbl->delegate->query(lbl->delegate, lbl, w, h);
 
 	if (w)
 		*w = 0;
@@ -106,17 +89,28 @@
 }
 
 void
-mlk_label_update(struct mlk_label *label, unsigned int ticks)
+mlk_label_update(struct mlk_label *lbl, unsigned int ticks)
 {
-	assert(mlk_label_ok(label));
+	assert(lbl);
 
-	MLK__DELEGATE_INVOKE(label->delegate, mlk_label_delegate, update, label, ticks);
+	if (lbl->delegate->update)
+		lbl->delegate->update(lbl->delegate, lbl, ticks);
 }
 
 void
-mlk_label_draw(const struct mlk_label *label)
+mlk_label_draw(const struct mlk_label *lbl)
 {
-	assert(mlk_label_ok(label));
+	assert(lbl);
+
+	if (lbl->delegate->draw)
+		lbl->delegate->draw(lbl->delegate, lbl);
+}
 
-	MLK__DELEGATE_INVOKE(label->delegate, mlk_label_delegate, draw, label);
+void
+mlk_label_finish(struct mlk_label *lbl)
+{
+	assert(lbl);
+
+	if (lbl->delegate->finish)
+		lbl->delegate->finish(lbl->delegate, lbl);
 }
--- a/libmlk-ui/mlk/ui/label.h	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/label.h	Thu Aug 10 19:57:00 2023 +0200
@@ -19,46 +19,167 @@
 #ifndef MLK_UI_LABEL_H
 #define MLK_UI_LABEL_H
 
-struct mlk_font;
+/**
+ * \file label.h
+ * \brief GUI label.
+ */
+
 struct mlk_label;
+struct mlk_label_delegate;
+struct mlk_style;
 
-struct mlk_label_style {
-	unsigned long color;
-	struct mlk_font *font;
-};
+/**
+ * \struct mlk_label
+ * \brief UI label text.
+ */
+struct mlk_label {
+	/**
+	 * (read-write)
+	 *
+	 * Position in x.
+	 */
+	int x;
 
-struct mlk_label_delegate {
-	void *data;
-	int (*query)(struct mlk_label_delegate *, const struct mlk_label *, unsigned int *, unsigned int *);
-	void (*update)(struct mlk_label_delegate *, struct mlk_label *, unsigned int);
-	void (*draw)(struct mlk_label_delegate *, const struct mlk_label *);
-};
+	/**
+	 * (read-write)
+	 *
+	 * Position in y.
+	 */
+	int y;
 
-struct mlk_label {
-	int x, y;
+	/**
+	 * (read-write, borrowed)
+	 *
+	 * Text to show.
+	 */
 	const char *text;
-	struct mlk_label_style *style;
+
+	/**
+	 * (read-write, borrowed)
+	 *
+	 * Label style.
+	 */
+	struct mlk_style *style;
+
+	/**
+	 * (read-write, borrowed)
+	 *
+	 * Label delegate.
+	 */
 	struct mlk_label_delegate *delegate;
 };
 
-extern struct mlk_label_style mlk_label_style;
+/**
+ * \struct mlk_label_delegate
+ * \brief Label delegate.
+ */
+struct mlk_label_delegate {
+	/*
+	 * (read-write, borrowed, optional)
+	 *
+	 * Arbitrary user data.
+	 */
+	void *data;
+
+	/**
+	 * (read-write)
+	 *
+	 * Query required dimensions to draw this label.
+	 *
+	 * \param self this delegate
+	 * \param lbl the label to query
+	 * \param w the width destination (maybe NULL)
+	 * \param h the height destination (maybe NULL)
+	 * \return 0 on success or -1 on error
+	 */
+	int (*query)(struct mlk_label_delegate *self,
+	             const struct mlk_label *lbl,
+	             unsigned int *w,
+	             unsigned int *h);
+
+	/**
+	 * (read-write, optional)
+	 *
+	 * Update the label.
+	 *
+	 * \param self this delegate
+	 * \param lbl the label to update
+	 * \param ticks number of ticks since last frame
+	 */
+	void (*update)(struct mlk_label_delegate *self,
+	               struct mlk_label *lbl,
+	               unsigned int ticks);
+
+	/**
+	 * (read-write, optional)
+	 *
+	 * Draw this label.
+	 *
+	 * \param self this delegate
+	 * \param lbl the label to update
+	 */
+	void (*draw)(struct mlk_label_delegate *self,
+	             const struct mlk_label *lbl);
+
+	/**
+	 * (read-write, optional)
+	 *
+	 * Cleanup this delegate associated with the label.
+	 *
+	 * \param self this delegate
+	 * \param lbl the underlying label
+	 */
+	void (*finish)(struct mlk_label_delegate *self,
+	               struct mlk_label *lbl);
+};
+
+/**
+ * \brief Default stateless delegate for label.
+ */
 extern struct mlk_label_delegate mlk_label_delegate;
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
-int
-mlk_label_ok(const struct mlk_label *);
-
-int
-mlk_label_query(const struct mlk_label *, unsigned int *, unsigned int *);
+/**
+ * Initialize the label with default values.
+ *
+ * This is not required if you use designated initializers.
+ *
+ * \pre lbl != NULL
+ * \param lbl the label to default initialize
+ * \param st style to use (or NULL to use a default)
+ * \param dt delegate to use (or NULL to use a default)
+ */
+void
+mlk_label_init(struct mlk_label *lbl,
+               struct mlk_style *st,
+               struct mlk_label_delegate *dt);
 
+/**
+ * Invoke ::mlk_label_delegate::query.
+ */
+int
+mlk_label_query(const struct mlk_label *lbl, unsigned int *w, unsigned int *h);
+
+/**
+ * Invoke ::mlk_label_delegate::update.
+ */
 void
-mlk_label_update(struct mlk_label *, unsigned int ticks);
+mlk_label_update(struct mlk_label *lbl, unsigned int ticks);
 
+/**
+ * Invoke ::mlk_label_delegate::draw.
+ */
 void
-mlk_label_draw(const struct mlk_label *);
+mlk_label_draw(const struct mlk_label *lbl);
+
+/**
+ * Invoke ::mlk_label_delegate::finish.
+ */
+void
+mlk_label_finish(struct mlk_label *lbl);
 
 #if defined(__cplusplus)
 }
--- a/libmlk-ui/mlk/ui/notify.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/notify.c	Thu Aug 10 19:57:00 2023 +0200
@@ -35,7 +35,7 @@
 #define WIDTH   (mlk_window.w / 2.5)
 #define HEIGHT  (mlk_window.h / 10)
 #define MAX     (4)
-#define FONT    (mlk_notify_style.text_font ? mlk_notify_style.text_font : mlk_ui_fonts[MLK_UI_FONT_INTERFACE])
+#define FONT    (mlk_notify_style.text_font ? mlk_notify_style.text_font : &mlk_ui_fonts[MLK_UI_FONT_INTERFACE])
 
 struct geo {
 	const struct mlk_theme *theme;
@@ -66,7 +66,7 @@
 	y  = mlk_notify_style.padding * (index + 1);
 	y += HEIGHT * index;
 
-	font = mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
+	font = &mlk_ui_fonts[MLK_UI_FONT_INTERFACE];
 
 	/* Content frame. */
 	geo->frame_x = x;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-ui/mlk/ui/style.c	Thu Aug 10 19:57:00 2023 +0200
@@ -0,0 +1,25 @@
+#include <assert.h>
+#include <string.h>
+
+#include "style.h"
+#include "ui.h"
+
+struct mlk_style mlk_style = {
+	.padding        = MLK_STYLE_PADDING,
+	.bg_color       = MLK_STYLE_BG_COLOR,
+	.fg_color       = MLK_STYLE_FG_COLOR,
+	.border_color   = MLK_STYLE_BORDER_COLOR,
+	.border_size    = MLK_STYLE_BORDER_SIZE,
+	.text_color     = MLK_STYLE_TEXT_COLOR,
+	.selected_color = MLK_STYLE_SELECTED_COLOR,
+	.animation      = MLK_STYLE_ANIMATION,
+	.text_font      = &mlk_ui_fonts[MLK_UI_FONT_INTERFACE]
+};
+
+void
+mlk_style_init(struct mlk_style *style)
+{
+	assert(style);
+
+	memset(style, 0, sizeof (*style));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-ui/mlk/ui/style.h	Thu Aug 10 19:57:00 2023 +0200
@@ -0,0 +1,34 @@
+#ifndef MLK_UI_STYLE_H
+#define MLK_UI_STYLE_H
+
+/* https://lospec.com/palette-list/duel */
+
+#define MLK_STYLE_PADDING               (10)
+#define MLK_STYLE_BG_COLOR              (0xf5f7faff)
+#define MLK_STYLE_FG_COLOR              (0x000000ff)
+#define MLK_STYLE_BORDER_COLOR          (0xcdd2daff)
+#define MLK_STYLE_BORDER_SIZE           (2)
+#define MLK_STYLE_TEXT_COLOR            (0x222323ff)
+#define MLK_STYLE_SELECTED_COLOR        (0x55b67dff)
+#define MLK_STYLE_ANIMATION             (500)
+
+struct mlk_font;
+
+struct mlk_style {
+	unsigned int padding;
+	unsigned long bg_color;
+	unsigned long fg_color;
+	unsigned long border_color;
+	unsigned int border_size;
+	unsigned long text_color;
+	unsigned long selected_color;
+	unsigned int animation;
+	struct mlk_font *text_font;
+};
+
+extern struct mlk_style mlk_style;
+
+void
+mlk_style_init(struct mlk_style *style);
+
+#endif /* MLK_UI_STYLE_H */
--- a/libmlk-ui/mlk/ui/ui.c	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/ui.c	Thu Aug 10 19:57:00 2023 +0200
@@ -43,36 +43,33 @@
         .data = b,                                                      \
         .datasz = sizeof (b),                                           \
         .size = s,                                                      \
-        .fontaddr = &mlk_ui_fonts[i]                                    \
+        .font = &mlk_ui_fonts[i]                                        \
 }
 
 static struct font_def {
 	const unsigned char *data;
 	const size_t datasz;
 	unsigned int size;
-	struct mlk_font **fontaddr;
-	struct mlk_font font;
+	struct mlk_font *font;
 } fonts[MLK_UI_FONT_LAST] = {
 	FONT_DEF(assets_fonts_opensans_regular, 14, MLK_UI_FONT_INTERFACE)
 };
 
-struct mlk_font *mlk_ui_fonts[MLK_UI_FONT_LAST] = {0};
+struct mlk_font mlk_ui_fonts[MLK_UI_FONT_LAST] = {0};
 
 int
 mlk_ui_init(void)
 {
 	struct font_def *def;
-	int err;
 
 	/* Open all fonts and set the appropriate pointer address. */
 	for (size_t i = 0; i < MLK_UTIL_SIZE(fonts); ++i) {
 		def = &fonts[i];
 
-		if ((err = mlk_font_openmem(&def->font, def->data, def->datasz, def->size)) < 0)
-			goto failed;
-
-		/* Reference this font into the catalog. */
-		*fonts[i].fontaddr = &fonts[i].font;
+		if (mlk_font_openmem(def->font, def->data, def->datasz, def->size) < 0) {
+			mlk_ui_finish();
+			return -1;
+		}
 	}
 
 #if defined(MLK_WITH_NLS)
@@ -80,11 +77,6 @@
 #endif
 
 	return 0;
-
-failed:
-	mlk_ui_finish();
-
-	return err;
 }
 
 void
--- a/libmlk-ui/mlk/ui/ui.h	Thu Aug 10 21:16:05 2023 +0200
+++ b/libmlk-ui/mlk/ui/ui.h	Thu Aug 10 19:57:00 2023 +0200
@@ -20,6 +20,7 @@
 #define MLK_UI_UI_H
 
 #include <mlk/core/core.h>
+#include <mlk/core/font.h>
 
 /* TODO: make this a global variable to allow modification of default theme. */
 /* https://lospec.com/palette-list/duel */
@@ -34,14 +35,12 @@
 
 enum mlk_align;
 
-struct mlk_font;
-
 enum mlk_ui_font {
 	MLK_UI_FONT_INTERFACE,
 	MLK_UI_FONT_LAST
 };
 
-extern struct mlk_font *mlk_ui_fonts[MLK_UI_FONT_LAST];
+extern struct mlk_font mlk_ui_fonts[MLK_UI_FONT_LAST];
 
 #if defined(__cplusplus)
 extern "C" {