From 08d70177f3217a9e6da6f7a9e50c17d73f60c7cf Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Mon, 16 Jan 2023 12:30:56 +0100
Subject: [PATCH] Add test app
---
CMakeLists.txt | 3 +-
testapp.c | 1240 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1242 insertions(+), 1 deletion(-)
create mode 100644 testapp.c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d03cca6..99da048 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -323,6 +323,7 @@ endif()
if(SDL3TTF_SAMPLES)
add_executable(glfont glfont.c)
add_executable(showfont showfont.c)
+ add_executable(testapp testapp.c)
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL)
@@ -334,7 +335,7 @@ if(SDL3TTF_SAMPLES)
target_link_libraries(glfont PRIVATE OpenGL::GL)
endif()
- foreach(prog glfont showfont)
+ foreach(prog glfont showfont testapp)
target_link_libraries(${prog} PRIVATE SDL3_ttf::${sdl3_ttf_export_name})
target_link_libraries(${prog} PRIVATE ${sdl3_target_name})
diff --git a/testapp.c b/testapp.c
new file mode 100644
index 0000000..7d4964c
--- /dev/null
+++ b/testapp.c
@@ -0,0 +1,1240 @@
+/*
+ testapp: An example of using the SDL_ttf library with OpenGL.
+ Copyright (C) 2001-2023 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* A simple program to test the text rendering feature of the TTF library,
+ * and find bugs
+ *
+ * <F1> for console help
+ *
+ * Use
+ * - fill/replace test_fonts[] with your fonts
+ * - replay a case, adding the log at line ~650 (search for 'replay')
+ * - add more string to test_strings[]
+ *
+ */
+
+const static int g_force_no_SDF = 0; /* make random fuzzer faster by disabling SDF rendering */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <libgen.h>
+
+#include "SDL3/SDL.h"
+#include "SDL3/SDL_ttf.h"
+
+
+static void help(void)
+{
+ SDL_Log("up/down : font size -/+");
+ SDL_Log("c/v : next/previous font");
+ SDL_Log("o/p : outline -/+");
+ SDL_Log("q/e : wrap size -/+");
+ SDL_Log("a : align wrap: left center right");
+ SDL_Log("w : wrap");
+ SDL_Log("u : underline");
+ SDL_Log("k : kerning");
+ SDL_Log("s : strike-through");
+ SDL_Log("b : bold");
+ SDL_Log("g/h : hinting -/+ (normal, light, light_subpix, mono, none)");
+ SDL_Log("i : italic");
+ SDL_Log("f : signed distance field");
+ SDL_Log("t : ticks elapsed for 50 rendering");
+ SDL_Log("d : display normal texture, no screen update, stream texture ");
+ SDL_Log("r : start/stop random test");
+ SDL_Log("m : render mode Solid/Blended/Shaded");
+ SDL_Log("n : change direction");
+ SDL_Log("9/0 : -/+ alpha color fg");
+ SDL_Log("7/8 : -/+ alpha color bg (Shaded only)");
+ SDL_Log("6 : invert bg/fg colors");
+ SDL_Log("345 : increase r/g/b fg color");
+ SDL_Log("2 : background color (Black->R->G->B->W)");
+ SDL_Log("<space> : next string/rendering function");
+ SDL_Log("<backspace> : previous string/rendering function");
+ SDL_Log("F1 : help");
+ SDL_Log("F2 : save current rendering to .bmp");
+}
+
+#define HAVE_LCD
+#define HAVE_SDF
+
+#define HAVE_SET_FONT_SIZE_FUNCTION
+// Need patch to set size dynamically
+// https://bugzilla.libsdl.org/show_bug.cgi?id=2487
+
+#define HAVE_ALL_WRAPPED_FUNCTIONS
+// Need patch to have all wrapped functions
+// https://bugzilla.libsdl.org/show_bug.cgi?id=4361
+
+#define HAVE_WRAP_ALIGN
+
+
+
+static int rand_n(int n);
+static void init_rand(void);
+
+static const char *test_fonts[] = {
+ "fonts/NotoColorEmoji.ttf", // Colored Emoji
+ "fonts/FletcherGothicFLF.ttf",
+#if 1
+ /* CFF/OpenType font (.otf) */
+ "fonts/ITCAvantGardeStd-Demi.ttf", // BUG 4266
+#endif
+ "fonts/DroidSansFallback.ttf", // xstart negative Jap
+ "fonts/Папка/Lazy.ttf",
+ "fonts/DroidSans.ttf", // no kerning here ?
+ "fonts/DejaVuSans.ttf",
+ "fonts/digital-7.ttf", // BUG 969
+ "fonts/HelveticaNeue-Regular.ttf",// BUG 2622
+ "fonts/ttf_amiga/amiga4ever pro2.ttf",
+ "fonts/ttf-bitstream-vera-1.10/VeraMoBI.ttf",
+ "fonts/ttf-bitstream-vera-1.10/VeraBd.ttf",
+ "fonts/ttf-bitstream-vera-1.10/Vera.ttf",
+ "fonts/nonscalable/sazanami-gothic.ttf", // BUG 190 crash?. Both Scalable and Fixed Sizes
+ "fonts/drakono.ttf", // BUG 2629 ........ ??????
+ "fonts/Lazy.ttf", // BUG 2468
+ "fonts/font_bug254.ttf", // BUG 254
+ "fonts/OpenSansEmoji.ttf", // BUG 3762
+#if 1
+ "fonts/nonscalable/pvfixed_20b.pcf.gz",
+ "fonts/nonscalable/pvfixed_20r.pcf.gz",
+ "fonts/nonscalable/7x13B-ISO8859-15.pcf.gz",
+ "fonts/nonscalable/vgasys.fon", // BUG 2574
+ "fonts/nonscalable/fixed8.fon", // BUG 2127
+#endif
+#if 0
+# include "fonts/fuzzing_corpora.h"
+#endif
+#if 0
+# include "fonts/android_fonts_others.h"
+# include "fonts/android_fonts.h"
+#endif
+ "fonts/Kaumudi.ttf"
+};
+static const int test_fonts_count = SDL_arraysize(test_fonts);
+
+
+static int wrap_size = 137;
+static int w_align = 0;
+static int outline = 0;
+static int font_style = 0;
+static int kerning = 1;
+static int wrap = 0;
+static int sdf = 0;
+static int hinting = 0;
+static int curr_str = 0;
+static int curr_font = 1;
+static int curr_size = 50;
+static int fg_alpha = 0;
+static int bg_alpha = 0;
+static int background_color = 0;
+
+static int seed = 0;
+static int print_elapsed_ticks = 0;
+static int update_screen_mode = 0;
+static int save_to_bmp = 0;
+
+/* RENDER_SOLID = 0, RENDER_BLENDED = 1, RENDER_SHADED = 2, RENDER_LCD = 3 } */
+static int render_mode = -1;
+static int render_mode_overwrite;
+static const char *render_mode_desc[] = { "Solid", "Blended", "Shaded", "LCD" };
+static const int render_mode_count = SDL_arraysize(render_mode_desc);
+
+static int direction = 0;
+static const struct {
+ const char *description;
+ int value;
+} directions[] = {
+ { "LTR", TTF_DIRECTION_LTR },
+ { "RTL", TTF_DIRECTION_RTL },
+ { "TTB", TTF_DIRECTION_TTB },
+ { "BTT", TTF_DIRECTION_BTT }
+};
+static const int direction_count = SDL_arraysize(directions);
+
+
+//static const char *hinting_desc[] = { "normal", "light", "light_subpix", "lcd_subpix", "mono", "none" };
+static const char *hinting_desc[] = { "normal", "light", "light_subpix", "mono", "none" };
+static const int hinting_count = SDL_arraysize(hinting_desc);
+
+static int mode_random_test = 0;
+static int random_cnt = 0;
+
+static int saved_curr_font = -1;
+static int saved_curr_size = -1;
+
+static SDL_Color boardcol = { 0, 0, 0, 0 };
+static SDL_Color textcol = { 255, 255, 255, 0 };
+
+
+static const char emoji[5] = { 0xF0, 0x9F, 0x98, 0x81, '\0'};
+
+static const char *test_strings[] = {
+// TMP BUG
+#if 0
+"وفي حالة كشف مربع يحتوي على لغم، يخسر اللاعب اللعبة.",
+#endif
+#if 1
+ "纸牌接龙",
+ //"空当接龙用一副没有大小王的52张扑克牌来玩,这些扑克牌被摆在8列中。",
+#endif
+ "ABC",
+ "The quick \n brown fox \n jumps over the lazy dog 0123456789",
+ "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", // test supixel
+ emoji,
+/* static const char emoji[5] = { 0xF0, 0x9F, 0x98, 0x81, '\0'}; */
+#if 1
+ "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "
+ "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "
+ "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "
+ ,
+#endif
+ "aTa kerning iTo",
+ "AV VA Te eT Tr rT Td TA LV Vd pV Vq bV", // kerning
+ "if fi ifi aif fai aifia substitution",
+ "abc \xc4\x80", // String would be both outline and bitmap for Sazami-Gothic
+#if 1
+ "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "
+ "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "
+ "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "
+ ,
+#endif
+ "abcdefghijklmnopqrstuvwxyz",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "0123456789",
+ "=",
+ "~",
+ "`~!@#$%^&*()_-+={}|[]\\;:'\",<.>/?",
+#if 1
+ "Å", // ystart negative with DroidSans
+ "A\n\b\nB",
+ "Tap Å",
+ /* xstart negative */
+ "Jap",
+ "A\315\241B", /* 'A' + U+0361 + 'B' */
+ "\315\241BC", /* '.' + U+0361 + 'B' + 'C' */
+ ".\315\241BC", /* '.' + U+0361 + 'B' + 'C' */
+ ".\315\241BC\naaaaa", /* '.' + U+0361 + 'B' + 'C' */
+ ".aaaaa\n.\315\241BC", /* '.' + U+0361 + 'B' + 'C' */
+
+ "aaa\n.\315\241BCaa\n.aaa\n.\315\241BCaaaaa", /* '.' + U+0361 + 'B' + 'C' */
+ "Tap Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å"
+ "Tap Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å"
+ "Tap Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å Å",
+#endif
+ "+", "2", ")", "|",
+ "a\tsdfsad.f..| I V I A AV A V D \n F G H ",
+ "é ê è à â ô î ï fi if ñ ç Ã Â",
+
+
+"Kl1AqvJAUOOKzdjpGTteM775hTYEuqvV b3EU0RZ88JIAMRVS7rMbyKsF1xMg9RTe",
+"CGOXraiYCL44XSlvqx825GvZT3HQYXNQcVNjgzrccX1eUar8nG0FZ3MsYdB5caGqiG7l7RJCyNZFRUVQ8rEVnc0TJVrY3ef4v8miQpVvYswTjjZKTZLwwFxLbsHhaDQ3",
+"7I8DRXPfbKUIl6SH5V6Twqw6mzEzTlDf",
+"JJsSGv1EA MpN9FIctQxi9D iHgEQZe2Wg",
+"xqKyuaT8H2xmySzWdbo wgMZ4Sp2BLUGj",
+"hUEKUunoouIjw6Cu jdXnPkQzMNGG7U8u",
+"4GDEgeCgEXwxoszBpriddAibgbhh36Vz",
+"FdkAi hx8B3QvmjFXovy64TzYwaZ0uoW8",
+"zAcp1V4PmI5dBv wtnbHqN1ISyrXB7P32",
+"lJq5w9GNhpqveQ67kxyQlgAwgQz1AAj3",
+"yi0jssXmCMjnFjl2rWs0rNIx51iVNLoI",
+"HT1BYxlX3z39XBFEw8JMNwYdWeQrO8h2",
+"aQmJI2hUruwhqvJeWL3 gZCGAZ09q67nR",
+"rxGWF OPfQdxUR0cYRenCccz5XgSpTDqf",
+"4NI1L2KbwybObecSDAAgb0K00oCEkf3E",
+"heBlACb AfcK9G85Gl6mBpBUiblc81FSe",
+"GwWx6pHvWyvxSu82PbJbZI UNwx9JSATu",
+"AFCQd25jnbBJ7LBbaXI3I5IeSwDXqME6",
+"lzSqw9t7hJ03AkTjWWUyd3KqrnGAvPJg",
+"pxwCKuWxUOrIMvqXGL 5fbibttAPNIJFC",
+"Fs6sFtGnRezLttwm8AbSKsuvLGbcqFbZ",
+"hEdVvdwWDwsDA23dX0NjDqzYEaURRC7a",
+"IBrdiqo3g0tj LkXz1a45DJD52tO8FJSw",
+"h5QYsL9S1cfsWzTyyFJ6Npq7vLi1tjEX",
+"zhUkVyCPdhWspT9kBQpOmmREmSU6GPW3",
+"Ud1ih3stL5nq00PJMRoA1Zd1QJi0mOzj",
+"iVppAFr5pGYa4oT8OozDi0oqGvqJg3Eg",
+"YC9YUpKq95nIe7D3ckdc6Yy1cEmmuqf1",
+"pzmZvs5j77aVaXXnPqzcuU9fW4Kfmiv5",
+"04ifd9OyA5XGsLTovRo04MnIKToW9Qu3",
+"iDJcbD5si6xPRcPRBEVeEhcJSs7n65SD",
+"a4oZMmgJQAa72o6sllH4n0zfJE5H0HlA",
+"5eSVmFkJMmPCRKdTZRJeuW71uhprmYHp",
+"LcnSHbxguPfqPNhdDR4XDc2qv01Q4Y1Y",
+"H3wT59MiQmEBZ7tYGMt1xMUu7wajECo6",
+"JNGUtcQz660ApgN54rk2UzpqWimO25Cy",
+"ss887dpFwjPaqAg53K6qZnc1NFiXc9WX",
+"y9Th4vRk1jSpKlzB5soK66ckzl3USZq6",
+"WGWY5YmWhaA5oKCoDmRA3n82XwclqvSP",
+"hvlSZ6jE2BU9ImjUjQiY255GA5ASfUUx",
+"e9o4tBCA9TCpilOI05UyHzes6s8lP9lQ",
+"gJyC26gZsCKR8wSp9kNMYKJRRgA3u45U1DWdzPCWv1SUEKi3Wdo3zNFTWiMcCfcl5A0MzOhbqRee7OP13NruY WP0ufGiB4W9RBWqgSy7umnE6puTyCc9WhPOzdLz168BhQwYetZkADWibObi8jcYajuUv54zxXkXQwC1B8lAi8rIH9lmIy0G10fQ832HKiLx"
+
+
+};
+static const int test_strings_count = SDL_arraysize(test_strings);
+static const char *font_path = NULL;
+
+static TTF_Font *font = NULL;
+static int iter = 0, sum = 0;
+
+static void quit(const char *msg)
+{
+ SDL_Log("ERROR: %s", msg);
+ SDL_Log("SDL_GetError: %s", SDL_GetError());
+ exit(1);
+}
+
+static void random_input(void);
+
+static int wait_for_input(void)
+{
+ int done = 0;
+ SDL_Event event;
+
+ while (!done) {
+ if (SDL_WaitEvent(&event) < 0) {
+ quit("Event handling");
+ }
+
+ switch (event.type) {
+ case SDL_EVENT_KEY_DOWN:
+ if (event.key.keysym.sym == SDLK_F1) {
+ help();
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_SPACE) {
+ iter++;
+ sum++;
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_BACKSPACE) {
+ iter--;
+ sum++;
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_DOWN) {
+ curr_size -= 1;
+ if (curr_size < -1) curr_size = -1;
+ done = 1;
+ SDL_Log("size: %d", curr_size);
+ }
+ if (event.key.keysym.sym == SDLK_UP) {
+ curr_size += 1;
+ done = 1;
+ SDL_Log("size: %d", curr_size);
+ }
+ if (event.key.keysym.sym == SDLK_c) {
+ curr_font -= 1;
+ if (curr_font < 0) curr_font = 0;
+ done = 1;
+ SDL_Log("Switch to font %s", test_fonts[curr_font]);
+ }
+ if (event.key.keysym.sym == SDLK_v) {
+ curr_font += 1;
+ done = 1;
+ if (curr_font >= test_fonts_count) curr_font = test_fonts_count - 1;
+ SDL_Log("Switch to font %s", test_fonts[curr_font]);
+ }
+
+ if (event.key.keysym.sym == SDLK_o) {
+ outline -= 1;
+ if (outline < -1) outline = -1;
+ done = 1;
+ SDL_Log("outline: %d", outline);
+ }
+ if (event.key.keysym.sym == SDLK_p) {
+ outline += 1;
+ done = 1;
+ SDL_Log("outline: %d", outline);
+ }
+ if (event.key.keysym.sym == SDLK_q) {
+ wrap_size -= 1;
+ done = 1;
+ SDL_Log("wrap_size: %d", wrap_size);
+ }
+ if (event.key.keysym.sym == SDLK_a) {
+ w_align += 1;
+ if (w_align == 3) w_align = 0;
+ done = 1;
+ SDL_Log("wrap_align: %d", w_align);
+ }
+ if (event.key.keysym.sym == SDLK_e) {
+ wrap_size += 1;
+ done = 1;
+ SDL_Log("wrap_size: %d", wrap_size);
+ }
+ if (event.key.keysym.sym == SDLK_i) {
+ int s = TTF_STYLE_ITALIC;
+ SDL_Log("italic %s", (font_style & s) ? "removed" : "added");
+ font_style ^= s;
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_b) {
+ int s = TTF_STYLE_BOLD;
+ SDL_Log("bold %s", (font_style & s) ? "removed" : "added");
+ font_style ^= s;
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_u) {
+ int s = TTF_STYLE_UNDERLINE;
+ SDL_Log("underline %s", (font_style & s) ? "removed" : "added");
+ font_style ^= s;
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_s) {
+ int s = TTF_STYLE_STRIKETHROUGH;
+ SDL_Log("strike-through %s", (font_style & s) ? "removed" : "added");
+ font_style ^= s;
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_k) {
+ done = 1;
+ kerning ^= 1;
+ if (kerning) {
+ SDL_Log("kerning allowed");
+ } else {
+ SDL_Log("kerning removed");
+ }
+ }
+ if (event.key.keysym.sym == SDLK_w) {
+ done = 1;
+ wrap ^= 1;
+ if (wrap) {
+ SDL_Log("wrap allowed");
+ } else {
+ SDL_Log("wrap removed");
+ }
+ }
+ if (event.key.keysym.sym == SDLK_f) {
+ done = 1;
+ sdf ^= 1;
+ if (sdf) {
+ SDL_Log("SDF allowed");
+ } else {
+ SDL_Log("SDF removed");
+ }
+ }
+ if (event.key.keysym.sym == SDLK_t) {
+ done = 1;
+ print_elapsed_ticks ^= 1;
+ if (print_elapsed_ticks) {
+ SDL_Log("print_elapsed_ticks displayed");
+ } else {
+ SDL_Log("print_elapsed_ticks hidden");
+ }
+ }
+ if (event.key.keysym.sym == SDLK_d) {
+ done = 1;
+ update_screen_mode += 1;
+ update_screen_mode %= 2;
+
+ if (update_screen_mode == 0) {
+ SDL_Log("texture displayed");
+ } else if (update_screen_mode == 1) {
+ SDL_Log("texture not displayed");
+ }
+ }
+ if (event.key.keysym.sym == SDLK_g) {
+ done = 1;
+ hinting -= 1;
+ if (hinting < 0) hinting = 0;
+ SDL_Log("hinting: %s", hinting_desc[hinting]);
+ }
+ if (event.key.keysym.sym == SDLK_h) {
+ done = 1;
+ hinting += 1;
+ hinting %= hinting_count;
+ SDL_Log("hinting: %s", hinting_desc[hinting]);
+ }
+ if (event.key.keysym.sym == SDLK_r) {
+ done = 1;
+ mode_random_test = 1;
+ random_cnt = 0;
+ SDL_Log("start random test");
+ }
+ if (event.key.keysym.sym == SDLK_m) {
+ done = 1;
+ render_mode += 1;
+ render_mode %= render_mode_count;
+ render_mode_overwrite = render_mode;
+ SDL_Log("render mode: %s", render_mode_desc[render_mode]);
+ }
+ if (event.key.keysym.sym == SDLK_n) {
+ done = 1;
+ direction += 1;
+ direction %= direction_count;
+ SDL_Log("direction: %s", directions[direction].description);
+ }
+ if (event.key.keysym.sym == SDLK_F2) {
+ done = 1;
+ save_to_bmp = 1;
+ }
+ if (event.key.keysym.sym == SDLK_9) {
+ done = 1;
+ fg_alpha -= 1;
+ if (fg_alpha < 0) fg_alpha = 0;
+ SDL_Log("color fg alpha = %d", fg_alpha);
+ }
+ if (event.key.keysym.sym == SDLK_0) {
+ done = 1;
+ fg_alpha += 1;
+ if (fg_alpha > 255) fg_alpha = 255;
+ SDL_Log("color fg alpha = %d", fg_alpha);
+ }
+ if (event.key.keysym.sym == SDLK_7) {
+ done = 1;
+ bg_alpha -= 1;
+ if (bg_alpha < 0) bg_alpha = 0;
+ SDL_Log("color bg alpha = %d", bg_alpha);
+ }
+ if (event.key.keysym.sym == SDLK_8) {
+ done = 1;
+ bg_alpha += 1;
+ if (bg_alpha > 255) bg_alpha = 255;
+ SDL_Log("color bg alpha = %d", bg_alpha);
+ }
+ if (event.key.keysym.sym == SDLK_6) {
+ SDL_Color tmp = textcol;
+ textcol = boardcol;
+ boardcol = tmp;
+ textcol.a = 0;
+ boardcol.a = 0;
+ SDL_Log("Invert BG / FG color");
+ done = 1;
+ }
+ if (event.key.keysym.sym == SDLK_3) {
+ done = 1;
+ textcol.r += 1;
+ SDL_Log("color fg: r=%d g=%d b=%d alpha=%d", textcol.r, textcol.g, textcol.b, textcol.a);
+ }
+ if (event.key.keysym.sym == SDLK_4) {
+ done = 1;
+ textcol.g += 1;
+ SDL_Log("color fg: r=%d g=%d b=%d alpha=%d", textcol.r, textcol.g, textcol.b, textcol.a);
+ }
+ if (event.key.keysym.sym == SDLK_5) {
+ done = 1;
+ textcol.b += 1;
+ SDL_Log("color fg: r=%d g=%d b=%d alpha=%d", textcol.r, textcol.g, textcol.b, textcol.a);
+ }
+ if (event.key.keysym.sym == SDLK_2) {
+ const char *str[6] = {"Black", "Red", "Green", "Blue", "White", "Gray" };
+ background_color += 1;
+ if (background_color == 6) background_color = 0;
+ SDL_Log("Background color '%s", str[background_color]);
+ done = 1;
+ }
+
+ if (event.key.keysym.sym == SDLK_ESCAPE) {
+ SDL_Log("ESC");
+ return 1;
+ }
+ break;
+ case SDL_EVENT_QUIT:
+ return 1;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+int main(void)
+{
+ SDL_Window *window = NULL;
+ SDL_Texture *text_texture = NULL;
+ SDL_Surface *text_surface = NULL;
+ SDL_Renderer *renderer = NULL;
+ const int windoww = 640;
+ const int windowh = 480;
+ const char *text;
+ char filename[256];
+ char infos[256];
+ int replay = 0;
+ int t1 = 0, t2 = 0, t_sum;
+ Uint64 T1 = 0, T2 = 0, T_sum, T_min;
+ int count, count_init;
+
+#define INIT_VARS \
+ t_sum = 0; \
+ T_sum = 0; \
+ T_min = 999999999999; \
+ count = count_init; \
+
+#define START_MEASURE \
+ t1 = SDL_GetTicks(); \
+ T1 = SDL_GetPerformanceCounter(); \
+
+
+#define END_MEASURE \
+ T2 = SDL_GetPerformanceCounter(); \
+ t2 = SDL_GetTicks(); \
+ \
+ t_sum += (t2 - t1); \
+ T_sum += (T2 - T1); \
+ T_min = SDL_min(T_min, T2 - T1); \
+
+
+
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ quit("SDL init failed");
+ }
+
+ if (TTF_Init() < 0) {
+ SDL_Quit();
+ quit("SDL_ttf init failed");
+ }
+
+ window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windoww, windowh, 0);
+ if (window == NULL) {
+ quit("SDL windowdow setup failed");
+ }
+
+ // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
+ // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2");
+ renderer = SDL_CreateRenderer(window, NULL, 0);
+ if (renderer == NULL) {
+ quit("SDL renderer setup failed");
+ }
+
+ /* Display help */
+ help();
+
+
+#if 0
+ /*****************************************/
+ /* Copy a log here to replay a rendering */
+ /*********************************** *****/
+
+ /* FreeType issue with FletcherGothicFLF, size=10 and outline at 9 -> error in FT_Glyph_To_Bitmap(). glyph '=' */
+ // replay=1; font_style=0; kerning=0; wrap=0; wrap_size=0; outline=8; curr_size=10; render_mode=0; curr_str=5; curr_font=0;
+ // do outline +1 (key p)
+ // --> SDL_GetError: Couldn't find glyph
+ //
+
+ /* FreeType issue with font/ITCAvantGardeStd-Demi.ttf glyph='Q' */
+ // replay=1; font_style=0; kerning=0; wrap=0; wrap_size=0; outline=0; curr_size=4; render_mode=0; curr_str=27; curr_font=1; hinting=3;
+ // do outline +1 (key p)
+ // --> SDL_GetError: Couldn't find glyph
+
+#endif
+
+ // color
+ // replay=1; font_style=0; kerning=0; wrap=0; wrap_size=354; outline=0; curr_size=7; render_mode=1; curr_str=63; curr_font=1522; hinting=0; fg_alpha=255; // light Blended
+
+ //replay=1; font_style=15; kerning=0; wrap=1; wrap_size=56; outline=0; curr_size=5; render_mode=1; curr_str=68; curr_font=3007; hinting=0; fg_alpha=128; // mono Blended
+
+#if 0
+ seed=1641805930; replay=1; font_style=9; kerning=1; sdf=1; wrap=0; wrap_size=661; w_align=2; outline=0; curr_size=20; render_mode=3; curr_str=14; curr_font=1777; hinting=1; fg_alpha=65; // light LCD
+#endif
+
+ //seed=1673390190; replay=1; font_style=12; kerning=0; sdf=1; wrap=0; wrap_size=91; w_align=0; outline=0; curr_size=16; render_mode=0; curr_str=14; curr_font=1288; hinting=0; fg_alpha=77; // none Solid
+
+ //seed=1673390190; replay=1; font_style=12; kerning=0; sdf=0; wrap=0; wrap_size=91; w_align=0; outline=0; curr_size=30; render_mode=1; curr_str=14; curr_font=1288; hinting=0; fg_alpha=77; // none Solid
+
+ //seed=1673390190; replay=1; font_style=9; kerning=1; sdf=0; wrap=1; wrap_size=94; w_align=2; outline=7; curr_size=42; render_mode=1; curr_str=75; curr_font=1997; hinting=1; fg_alpha=90; // light Blended
+
+
+
+
+
+
+
+ if (replay) {
+ SDL_Log("Replay with string _%s_", test_strings[curr_str]);
+ }
+
+
+ while (1)
+ {
+
+ /* Normal mode <space>, try all combination {strings}x{render_mode} and exit
+ This updates "render_mode" and "curr_str" */
+ if (!mode_random_test && !replay) {
+ if (iter <= 0) {
+ iter = 0;
+ }
+
+ if (iter >= render_mode_count * test_strings_count) {
+ SDL_Log("End of rendering!");
+ break;
+ } else {
+ render_mode = iter / test_strings_count;
+ curr_str = iter - test_strings_count * render_mode;
+ }
+ }
+
+ if (render_mode_overwrite) {
+ render_mode = render_mode_overwrite;
+ }
+
+
+ textcol.a = fg_alpha;
+ boardcol.a = bg_alpha;
+
+ /* Set all parameters coming from random or user input */
+#if 0
+ /* Force a parameter */
+ curr_font = 1250;
+ curr_size = 1;
+ curr_size &=0x3;
+#endif
+
+#if 0
+ /* From a specific seed, jump to a specific iteration */
+ {
+ static int skip = 1046;
+ if (skip) {
+ skip--;
+ goto next_loop;
+ }
+ }
+#endif
+
+ if (saved_curr_font != curr_font) {
+ if (font) {
+ TTF_CloseFont(font);
+ }
+ saved_curr_font = curr_font;
+ saved_curr_size = curr_size;
+ font_path = test_fonts[curr_font];
+ SDL_Log("TTF_OpenFont: %s", font_path);
+ font = TTF_OpenFont(font_path, curr_size);
+ if (!font) {
+#if 1
+ quit("Font load failed");
+#else
+ SDL_Log("Font load failed");
+ saved_curr_font = -1;
+ goto next_loop;
+#endif
+ }
+ }
+
+ if (saved_curr_size != curr_size) {
+#if defined(HAVE_SET_FONT_SIZE_FUNCTION)
+ TTF_SetFontSize(font, curr_size);
+#else
+ if (font) {
+ TTF_CloseFont(font);
+ }
+ font_path = test_fonts[curr_font];
+ SDL_Log("Re-TTF_OpenFont: %s to change size from %d to %d", font_path, saved_curr_size, curr_size);
+ font = TTF_OpenFont(font_path, curr_size);
+ if (!font) {
+#if 1
+ quit("Font load failed (2)");
+#else
+ SDL_Log("Font load failed (2)");
+ saved_curr_font = -1;
+ goto next_loop;
+#endif
+
+ }
+#endif
+ saved_curr_size = curr_size;
+ }
+
+ TTF_SetFontDirection(font, directions[direction].value);
+ // TTF_SetScript(HB_SCRIPT_ARABIC);
+ // TTF_SetScript(HB_SCRIPT_HAN);
+
+ {
+ int tmp;
+ tmp = TTF_GetFontOutline(font);
+ if (tmp != outline) {
+ TTF_SetFontOutline(font, outline);
+ }
+ tmp = TTF_GetFontStyle(font);
+ if (tmp != font_style) {
+ TTF_SetFontStyle(font, font_style);
+ }
+ tmp = TTF_GetFontKerning(font);
+ if (tmp != kerning) {
+ TTF_SetFontKerning(font, kerning);
+ }
+#if defined(HAVE_SDF)
+ tmp = TTF_GetFontSDF(font);
+ if (tmp != sdf) {
+ TTF_SetFontSDF(font, sdf);
+ }
+#endif
+
+
+
+ {
+ // static const char *hinting_desc[] = { "normal", "light", "light_subpix", "mono", "none" };
+ // static const char *hinting_desc[] = { "normal", "light", "light_subpix", "lcd_subpix", "mono", "none" };
+ int h = 0;
+ if (hinting == 0) h = TTF_HINTING_NORMAL;
+ if (hinting == 1) h = TTF_HINTING_LIGHT;
+ if (hinting == 2) h = 4; // TTF_HINTING_LIGHT_SUBPIXEL;
+ // if (hinting == 3) h = 5; // TTF_HINTING_LCD_SUBPIXEL;
+ if (hinting == 3) h = TTF_HINTING_MONO;
+ if (hinting == 4) h = TTF_HINTING_NONE;
+ tmp = TTF_GetFontHinting(font);
+ if (tmp != h) {
+ TTF_SetFontHinting(font, h);
+ }
+ }
+ }
+
+
+ /* Get some console output out in case we crash next... */
+ if (! mode_random_test) {
+ char title[1024];
+ snprintf(title, sizeof(title) - 1, "%s Sz=%d outline=%d Hinting=%s %s",
+ render_mode_desc[render_mode],
+ curr_size,
+ outline,
+ hinting_desc[hinting],
+ basename((char*)font_path));
+
+ if (save_to_bmp) {
+ snprintf(filename, sizeof(filename) - 1 ,
+ "Render=%s
(Patch may be truncated, please check the link at the top of this post.)