From ab4b0ebb4151d939bbf77eb331920146d04b4f20 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sat, 19 Oct 2024 09:09:52 -0700 Subject: [PATCH] Make text_render stripping leading whitespace a text_setting option --- src/game/gui/label.c | 4 ++-- src/game/gui/text_render.c | 45 +++++++++++++++++++++----------------- src/game/gui/text_render.h | 5 +++-- testing/test_text_render.c | 28 +++++++++++++++--------- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/game/gui/label.c b/src/game/gui/label.c index 4cc5265cd..f43e4f2bc 100644 --- a/src/game/gui/label.c +++ b/src/game/gui/label.c @@ -45,8 +45,8 @@ component *label_create_with_width(const text_settings *tconf, const char *text, int tsize = text_char_width(tconf); int w, h; - w = text_find_max_strlen(max_width / tsize, text); - h = text_find_line_count(TEXT_HORIZONTAL, w, 0, strlen(text), text) * 8; // fonts are all 8 high? + w = text_find_max_strlen(tconf, max_width / tsize, text); + h = text_find_line_count(tconf, w, 0, strlen(text), text) * 8; // fonts are all 8 high? component_set_size_hints(c, w, h); diff --git a/src/game/gui/text_render.c b/src/game/gui/text_render.c index f315e32e8..b3e07a002 100644 --- a/src/game/gui/text_render.c +++ b/src/game/gui/text_render.c @@ -14,6 +14,7 @@ void text_defaults(text_settings *settings) { settings->cdisabled = 0xC0; settings->cshadow = 0xC0; settings->cspacing = 0; + settings->strip_leading_whitespace = false; } int text_render_char(const text_settings *settings, text_mode state, int x, int y, char ch) { @@ -72,18 +73,20 @@ int text_render_char(const text_settings *settings, text_mode state, int x, int return (*sur)->w; } -int text_find_max_strlen(int max_chars, const char *ptr) { +int text_find_max_strlen(const text_settings *settings, int max_chars, const char *ptr) { int i = 0; int len = strlen(ptr); // Skip whitespace at the start of the string - /*for(i = 0; i < len; i++) { - if(ptr[i] != ' ') - break; - }*/ - /*if(i == len) { - return i; - }*/ + if(settings->strip_leading_whitespace) { + for(i = 0; i < len; i++) { + if(ptr[i] != ' ') + break; + } + if(i == len) { + return i; + } + } // Walk through the rest of the string int last_space = i; @@ -156,16 +159,16 @@ int text_char_width(const text_settings *settings) { return 6; } -int text_find_line_count(text_direction dir, int cols, int rows, int len, const char *text) { +int text_find_line_count(const text_settings *settings, int cols, int rows, int len, const char *text) { int ptr = 0; int lines = 0; while(ptr < len) { // Find out how many characters for this row/col int line_len; - if(dir == TEXT_HORIZONTAL) - line_len = text_find_max_strlen(cols, text + ptr); + if(settings->direction == TEXT_HORIZONTAL) + line_len = text_find_max_strlen(settings, cols, text + ptr); else - line_len = text_find_max_strlen(rows, text + ptr); + line_len = text_find_max_strlen(settings, rows, text + ptr); ptr += line_len; lines++; @@ -183,7 +186,7 @@ void text_render(const text_settings *settings, text_mode mode, int x, int y, in int charh = size + settings->lspacing; int rows = (yspace + settings->lspacing) / charh; int cols = (xspace + settings->cspacing) / charw; - int fit_lines = text_find_line_count(settings->direction, cols, rows, len, text); + int fit_lines = text_find_line_count(settings, cols, rows, len, text); int start_x = x + settings->padding.left; int start_y = y + settings->padding.top; @@ -231,9 +234,9 @@ void text_render(const text_settings *settings, text_mode mode, int x, int y, in // Find out how many characters for this row/col if(settings->direction == TEXT_HORIZONTAL) - line_len = text_find_max_strlen(cols, text + ptr); + line_len = text_find_max_strlen(settings, cols, text + ptr); else - line_len = text_find_max_strlen(rows, text + ptr); + line_len = text_find_max_strlen(settings, rows, text + ptr); real_len = line_len; // If line ends in linebreak, skip it from calculation. @@ -243,11 +246,13 @@ void text_render(const text_settings *settings, text_mode mode, int x, int y, in // Skip spaces int k = 0; - /*for(; k < line_len; k++) { - if(text[ptr + k] != ' ') - break; - real_len--; - }*/ + if(settings->strip_leading_whitespace) { + for(; k < line_len; k++) { + if(text[ptr + k] != ' ') + break; + real_len--; + } + } // Find total size of this line and set newline start coords switch(settings->direction) { diff --git a/src/game/gui/text_render.h b/src/game/gui/text_render.h index 52ad62e38..79ae60683 100644 --- a/src/game/gui/text_render.h +++ b/src/game/gui/text_render.h @@ -72,13 +72,14 @@ typedef struct { uint8_t shadow; uint8_t cspacing; uint8_t lspacing; + bool strip_leading_whitespace; bool wrap; } text_settings; // New text rendering functions void text_defaults(text_settings *settings); -int text_find_max_strlen(int max_chars, const char *ptr); -int text_find_line_count(text_direction dir, int cols, int rows, int len, const char *text); +int text_find_max_strlen(const text_settings *settings, int max_chars, const char *ptr); +int text_find_line_count(const text_settings *settings, int cols, int rows, int len, const char *text); int text_render_char(const text_settings *settings, text_mode mode, int x, int y, char ch); void text_render(const text_settings *settings, text_mode mode, int x, int y, int w, int h, const char *text); int text_char_width(const text_settings *settings); diff --git a/testing/test_text_render.c b/testing/test_text_render.c index 5ee283f28..654ec5153 100644 --- a/testing/test_text_render.c +++ b/testing/test_text_render.c @@ -3,23 +3,31 @@ #include void test_text_find_max_strlen(void) { - CU_ASSERT(text_find_max_strlen(10, " AAAAAAAAAA") == + text_settings tconf; + text_defaults(&tconf); + tconf.strip_leading_whitespace = true; + CU_ASSERT(text_find_max_strlen(&tconf, 10, " AAAAAAAAAA") == 20); // Space should be disregarded and only 10 accepted. Advance should be 20. - CU_ASSERT(text_find_max_strlen(10, "AAAAAAAAAA") == 10); // This should go on one line - CU_ASSERT(text_find_max_strlen(10, "AAAAAAAAAAA") == + tconf.strip_leading_whitespace = false; + CU_ASSERT_EQUAL(text_find_max_strlen(&tconf, 10, " AAAAAAAAAA"), + 9); // Space should NOT be disregarded and only 10 accepted. Advance should be 20. + CU_ASSERT(text_find_max_strlen(&tconf, 10, "AAAAAAAAAA") == 10); // This should go on one line + CU_ASSERT(text_find_max_strlen(&tconf, 10, "AAAAAAAAAAA") == 11); // This should go on one line, too, even though it's too long - CU_ASSERT(text_find_max_strlen(10, "AAAAAAAAAA BBBB") == + CU_ASSERT(text_find_max_strlen(&tconf, 10, "AAAAAAAAAA BBBB") == 10); // Only first string should be taken into account (10). Space should be disregarded. - CU_ASSERT(text_find_max_strlen(10, "AAAAAAAAAAA BBBB") == - 11); // Only first string should be taken into account (11) - CU_ASSERT(text_find_max_strlen(10, "AA\n") == 3); // Should advance 2 chars + line ending (3) - CU_ASSERT(text_find_max_strlen(14, "I CAN HAS CHEESEBURGER") == + CU_ASSERT(text_find_max_strlen(&tconf, 10, "AAAAAAAAAAA BBBB") == + 11); // Only first string should be taken into account (11) + CU_ASSERT(text_find_max_strlen(&tconf, 10, "AA\n") == 3); // Should advance 2 chars + line ending (3) + CU_ASSERT(text_find_max_strlen(&tconf, 14, "I CAN HAS CHEESEBURGER") == 9); // Should wordwrap. Skip spaces to next line. (9) } void test_text_find_line_count(void) { - CU_ASSERT(text_find_line_count(TEXT_HORIZONTAL, 5, 5, strlen("AAAAAAAAA"), "AAAAAAAAA") == 1); - CU_ASSERT(text_find_line_count(TEXT_HORIZONTAL, 5, 5, 11, "AAA AAA AAA") == 3); + text_settings tconf; + text_defaults(&tconf); + CU_ASSERT(text_find_line_count(&tconf, 5, 5, strlen("AAAAAAAAA"), "AAAAAAAAA") == 1); + CU_ASSERT(text_find_line_count(&tconf, 5, 5, 11, "AAA AAA AAA") == 3); } void text_render_test_suite(CU_pSuite suite) {