Commit eafdbe2d1cd0f85e7e2157950384e513de95abb3

Thomas de Grivel 2023-12-02T21:19:03

sdl2_font

diff --git a/libc3/window/Makefile b/libc3/window/Makefile
index 3d58339..f9a3a5b 100644
--- a/libc3/window/Makefile
+++ b/libc3/window/Makefile
@@ -13,6 +13,7 @@
 build:
 	${MAKE} ${LIB}
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo build; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 build; fi
 
 all:
 	${MAKE} build
@@ -23,20 +24,25 @@ all:
 asan:
 	${MAKE} ${LIB_ASAN}
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo asan; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 asan; fi
 
 clean:
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo clean; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 clean; fi
 
 clean_cov:
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo clean_cov; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 clean_cov; fi
 
 cov:
 	${MAKE} ${LIB_COV}
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo cov; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 cov; fi
 
 debug:
 	${MAKE} ${LIB_DEBUG}
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo debug; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 debug; fi
 
 demo: build
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo demo; fi
@@ -52,9 +58,11 @@ demo_gl_debug: debug
 
 distclean:
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo distclean; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 distclean; fi
 
 gcovr:
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo gcovr; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 gcovr; fi
 
 gdb_demo: debug
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo gdb_demo; fi
@@ -69,6 +77,7 @@ install:
 	${LIBTOOL} --tag=CC --mode=install ${INSTALL} -o ${OWNER} -g ${GROUP} -m 0644 ${LIB} ${prefix}/lib
 	${LIBTOOL} --finish ${prefix}/lib
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo install; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 install; fi
 
 lldb_demo: debug
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo lldb_demo; fi
@@ -78,6 +87,7 @@ lldb_demo_gl: debug
 
 test:
 	if ${HAVE_CAIRO}; then ${MAKE} -C cairo test; fi
+	if ${HAVE_SDL2}; then ${MAKE} -C sdl2 test; fi
 
 update_sources:
 	./update_sources
diff --git a/libc3/window/cairo/demo/window_cairo_demo.c b/libc3/window/cairo/demo/window_cairo_demo.c
index 90362ba..91d02ac 100644
--- a/libc3/window/cairo/demo/window_cairo_demo.c
+++ b/libc3/window/cairo/demo/window_cairo_demo.c
@@ -116,7 +116,8 @@ bool window_cairo_demo_render (s_window_cairo *window,
   if (! window_animate((s_window *) window))
     return false;
   seq = window->sequence + window->sequence_pos;
-  seq->render(seq, window, cr);
+  if (! seq->render(seq, window, cr))
+    return false;
   /* text */
   cairo_set_font_size(cr, 20);
   cairo_select_font_face(cr, "Courier New",
diff --git a/libc3/window/sdl2/configure b/libc3/window/sdl2/configure
index a86f46c..459ee56 100755
--- a/libc3/window/sdl2/configure
+++ b/libc3/window/sdl2/configure
@@ -43,6 +43,7 @@ LDFLAGS="--shared -no-undefined ${LDFLAGS}"
 LIBS="$LIBS -rpath ${PREFIX}/lib"
 config_asan
 config_gnu
+pkg_config ftgl
 pkg_config gl
 pkg_config glu
 pkg_config sdl2
diff --git a/libc3/window/sdl2/demo/configure b/libc3/window/sdl2/demo/configure
index 832befc..52d442f 100755
--- a/libc3/window/sdl2/demo/configure
+++ b/libc3/window/sdl2/demo/configure
@@ -49,6 +49,7 @@ CPPFLAGS="$CPPFLAGS -DGL_SILENCE_DEPRECATION=1"
 CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
 config_asan
 config_gnu
+pkg_config ftgl
 pkg_config gl
 pkg_config glu
 pkg_config sdl2
diff --git a/libc3/window/sdl2/demo/window_sdl2_demo.c b/libc3/window/sdl2/demo/window_sdl2_demo.c
index 8c0776d..3235f1c 100644
--- a/libc3/window/sdl2/demo/window_sdl2_demo.c
+++ b/libc3/window/sdl2/demo/window_sdl2_demo.c
@@ -15,10 +15,14 @@
 #include <libc3/c3.h>
 #include "../../window.h"
 #include "../window_sdl2.h"
+#include "../sdl2_font.h"
 #include "bg_rect.h"
 
 #define WINDOW_SDL2_DEMO_SEQUENCE_COUNT 1
 
+//static s_sdl2_font g_font_computer_modern;
+static s_sdl2_font g_font_courier_new;
+
 static bool window_sdl2_demo_button (s_window_sdl2 *window, u8 button,
                                      sw x, sw y);
 static bool window_sdl2_demo_key (s_window_sdl2 *window,
@@ -26,8 +30,8 @@ static bool window_sdl2_demo_key (s_window_sdl2 *window,
 static bool window_sdl2_demo_load (s_window_sdl2 *window);
 static bool window_sdl2_demo_render (s_window_sdl2 *window,
                                      void *context);
-bool window_sdl2_demo_resize (s_window_sdl2 *window,
-                              uw w, uw h);
+static bool window_sdl2_demo_resize (s_window_sdl2 *window,
+                                     uw w, uw h);
 
 int main (int argc, char **argv)
 {
@@ -101,6 +105,9 @@ bool window_sdl2_demo_load (s_window_sdl2 *window)
     assert(window->sequence_count == WINDOW_SDL2_DEMO_SEQUENCE_COUNT);
     return false;
   }
+  if (! sdl2_font_init(&g_font_courier_new,
+                       "fonts/Courier New/Courier New.ttf"))
+    return false;
   window_sdl2_sequence_init(window->sequence, 8.0,
                             "01. Background rectangles",
                             bg_rect_load, bg_rect_render);
@@ -145,20 +152,39 @@ bool window_sdl2_demo_render (s_window_sdl2 *window,
   seq = window->sequence + window->sequence_pos;
   if (! seq->render(seq, window, context))
     return false;
-  /* progress bar */
+  /* 2D */
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
-  glOrtho(0, window->w, window->h, 0, -1, 1);
+  glOrtho(0, window->w, 0, window->h, -1, 1);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
+  glDisable(GL_DEPTH_TEST);
+  sdl2_font_set_size(&g_font_courier_new, 20);
+  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+  glPushMatrix();
+  glTranslatef(19.0f, 29.0f, 0.0f);
+  sdl2_font_render_text(&g_font_courier_new, seq->title);
+  glTranslatef( 2.0f, 0.0f, 0.0f);
+  sdl2_font_render_text(&g_font_courier_new, seq->title);
+  glTranslatef( 0.0f, 2.0f, 0.0f);
+  sdl2_font_render_text(&g_font_courier_new, seq->title);
+  glTranslatef(-2.0f, 0.0f, 0.0f);
+  sdl2_font_render_text(&g_font_courier_new, seq->title);
+  glPopMatrix();
+  glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+  glPushMatrix();
+  glTranslatef(20.0f, 30.0f, 0.0f);
+  sdl2_font_render_text(&g_font_courier_new, seq->title);
+  glPopMatrix();
+  /* progress bar */
   glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-  glRectd(19, window->h - 12,
+  glRectd(19, 11,
           19 + (window->w - 40.0) * seq->t / seq->duration + 2,
-          window->h - 12 + 4);
+          11 + 4);
   glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-  glRectd(20, window->h - 11,
+  glRectd(20, 12,
           20 + (window->w - 40.0) * seq->t / seq->duration,
-          window->h - 11 + 2);
+          12 + 2);
   return true;
 }
 
diff --git a/libc3/window/sdl2/sdl2_font.c b/libc3/window/sdl2/sdl2_font.c
new file mode 100644
index 0000000..5c55f7d
--- /dev/null
+++ b/libc3/window/sdl2/sdl2_font.c
@@ -0,0 +1,59 @@
+/* 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 "sdl2_font.h"
+
+void sdl2_font_clean (s_sdl2_font *font)
+{
+  assert(font);
+  ftglDestroyFont(font->ftgl_font);
+  str_clean(&font->path);
+  str_clean(&font->real_path);
+}
+
+s_sdl2_font * sdl2_font_init (s_sdl2_font *font, const s8 *path)
+{
+  assert(font);
+  assert(path);
+  str_init_copy_1(&font->path, path);
+  if (! file_search(&font->path, sym_1("r"), &font->real_path)) {
+    warnx("sdl2_font_init(%s): file not found", path);
+    str_clean(&font->path);
+    return NULL;
+  }
+  font->ftgl_font = ftglCreateTextureFont(font->real_path.ptr.ps8);
+  if (! font->ftgl_font) {
+    warnx("sdl2_font_init(%s): Error loading font",
+          font->real_path.ptr.ps8);
+    str_clean(&font->path);
+    str_clean(&font->real_path);
+    return NULL;
+  }
+  font->size = 0;
+  font->resolution = 72;
+  return font;
+}
+
+void sdl2_font_set_size (const s_sdl2_font *font, uw size)
+{
+  assert(font);
+  assert(size);
+  ftglSetFontFaceSize(font->ftgl_font, size, font->resolution);
+}
+
+void sdl2_font_render_text (const s_sdl2_font *font, const s8 *p)
+{
+  ftglRenderFont(font->ftgl_font, p, FTGL_RENDER_ALL);
+}
diff --git a/libc3/window/sdl2/sdl2_font.h b/libc3/window/sdl2/sdl2_font.h
new file mode 100644
index 0000000..7339d91
--- /dev/null
+++ b/libc3/window/sdl2/sdl2_font.h
@@ -0,0 +1,31 @@
+/* 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_SDL2_SDL2_FONT_H
+#define LIBC3_WINDOW_SDL2_SDL2_FONT_H
+
+#include <assert.h>
+#include <err.h>
+#include "types.h"
+
+/* Stack-allocation compatible functions, call sdl2_font_clean after
+   use. */
+void          sdl2_font_clean (s_sdl2_font *font);
+s_sdl2_font * sdl2_font_init (s_sdl2_font *font, const s8 *path);
+
+/* Operators. */
+void sdl2_font_set_size (const s_sdl2_font *font, uw size);
+
+/* Observers */
+void sdl2_font_render_text (const s_sdl2_font *font, const s8 *p);
+
+#endif /* LIBC3_WINDOW_SDL2_SDL2_FONT_H */
diff --git a/libc3/window/sdl2/sources.mk b/libc3/window/sdl2/sources.mk
index 74b2d89..f4e58e5 100644
--- a/libc3/window/sdl2/sources.mk
+++ b/libc3/window/sdl2/sources.mk
@@ -1,8 +1,10 @@
 # sources.mk generated by update_sources
 HEADERS = \
+	sdl2_font.h \
 	types.h \
 	window_sdl2.h \
 
 SOURCES = \
+	sdl2_font.c \
 	window_sdl2.c \
 
diff --git a/libc3/window/sdl2/sources.sh b/libc3/window/sdl2/sources.sh
index 5f8490d..06c8a70 100644
--- a/libc3/window/sdl2/sources.sh
+++ b/libc3/window/sdl2/sources.sh
@@ -1,3 +1,3 @@
 # sources.sh generated by update_sources
-HEADERS='types.h window_sdl2.h '
-SOURCES='window_sdl2.c '
+HEADERS='sdl2_font.h types.h window_sdl2.h '
+SOURCES='sdl2_font.c window_sdl2.c '
diff --git a/libc3/window/sdl2/types.h b/libc3/window/sdl2/types.h
index 95b697b..553def1 100644
--- a/libc3/window/sdl2/types.h
+++ b/libc3/window/sdl2/types.h
@@ -21,6 +21,7 @@
 #include <SDL.h>
 #include <GL/gl.h>
 #include <GL/glu.h>
+#include <FTGL/ftgl.h>
 #include <libc3/types.h>
 #include "../types.h"
 
@@ -60,6 +61,14 @@ typedef bool (*f_window_sdl2_sequence_render) (s_sequence *seq,
                                                s_window_sdl2 *window,
                                                void *context);
 
+struct sdl2_font {
+  FTGLfont *ftgl_font;
+  u32 size;
+  u32 resolution;
+  s_str path;
+  s_str real_path;
+};
+
 struct rgb {
   double r;
   double g;
diff --git a/libc3/window/sdl2/window_sdl2.c b/libc3/window/sdl2/window_sdl2.c
index d1db5af..dfa5611 100644
--- a/libc3/window/sdl2/window_sdl2.c
+++ b/libc3/window/sdl2/window_sdl2.c
@@ -125,10 +125,12 @@ bool window_sdl2_run (s_window_sdl2 *window)
   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+  /*
   SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
-                      SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
-  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
-  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+                      SDL_GL_CONTEXT_PROFILE_CORE);
+  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
+  */
   window->sdl_window = SDL_CreateWindow(window->title,
                                         window->x, window->y,
                                         window->w, window->h,
@@ -150,13 +152,11 @@ bool window_sdl2_run (s_window_sdl2 *window)
     fprintf(stderr, "OpenGL initialization error: %s\n", gluErrorString(error));
     return false;
   }
-  /*
   if (SDL_GL_MakeCurrent(window->sdl_window, context) < 0) {
     warnx("window_sdl2_run: failed to make OpenGL context current: %s",
           SDL_GetError());
     return false;
   }
-  */
   SDL_GL_SetSwapInterval(1);
   if (! window->load(window)) {
     warnx("window_sdl2_run: window->load => false");