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");