From eb8649ba42f86159bd51b1ee366bd3291c05aafc Mon Sep 17 00:00:00 2001 From: Marcio T Date: Fri, 23 Jul 2021 16:02:39 -0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=BA=20Fix=20and=20optimize=20FTDI=20Ev?= =?UTF-8?q?e=20Touch=20Interface=20(#22427)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ftdi_eve_lib/basic/commands.cpp | 26 ++++++++-- .../ftdi_eve_lib/basic/commands.h | 1 + .../ftdi_eve_lib/extended/text_box.cpp | 50 +++++++++---------- .../ftdi_eve_lib/extended/unicode/unicode.cpp | 17 ++++--- .../ftdi_eve_lib/extended/unicode/unicode.h | 4 +- .../generic/about_screen.cpp | 10 ++-- .../confirm_user_request_alert_box.cpp | 9 +--- .../generic/confirm_user_request_alert_box.h | 1 - 8 files changed, 66 insertions(+), 52 deletions(-) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp index 47ce1c700d..48d60a37ac 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp @@ -902,6 +902,7 @@ bool CLCD::CommandFifo::has_fault() { } #if FTDI_API_LEVEL == 800 + void CLCD::CommandFifo::start() { if (command_write_ptr == 0xFFFFFFFFul) { command_write_ptr = mem_read_32(REG::CMD_WRITE) & 0x0FFF; @@ -979,12 +980,13 @@ template bool CLCD::CommandFifo::_write_unaligned(T data, uint16_t len template bool CLCD::CommandFifo::write(T data, uint16_t len) { const uint8_t padding = MULTIPLE_OF_4(len) - len; - - uint8_t pad_bytes[] = {0, 0, 0, 0}; + const uint8_t pad_bytes[] = { 0, 0, 0, 0 }; return _write_unaligned(data, len) && _write_unaligned(pad_bytes, padding); } -#else + +#else // FTDI_API_LEVEL != 800 ... + void CLCD::CommandFifo::start() { } @@ -1042,13 +1044,29 @@ template bool CLCD::CommandFifo::write(T data, uint16_t len) { mem_write_bulk(REG::CMDB_WRITE, data, len, padding); return true; } -#endif + +#endif // ... FTDI_API_LEVEL != 800 template bool CLCD::CommandFifo::write(const void*, uint16_t); template bool CLCD::CommandFifo::write(progmem_str, uint16_t); // CO_PROCESSOR COMMANDS +void CLCD::CommandFifo::str(const char * data, size_t maxlen) { + // Write the string without the terminating '\0' + const size_t len = strnlen(data, maxlen); + write(data, len); + + // If padding was added by the previous write, then + // the string is terminated. Otherwise write four + // more zeros. + const uint8_t padding = MULTIPLE_OF_4(len) - len; + if (padding == 0) { + const uint8_t pad_bytes[] = {0, 0, 0, 0}; + write(pad_bytes, 4); + } +} + void CLCD::CommandFifo::str(const char * data) { write(data, strlen(data)+1); } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h index eea24b06bd..5ce628fd36 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h @@ -248,6 +248,7 @@ class CLCD::CommandFifo { void keys (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options); // Sends the string portion of text, button, toggle and keys. + void str (const char * data, size_t maxlen); void str (const char * data); void str (progmem_str data); diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp index f3f518359c..0701e7d682 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp @@ -29,31 +29,31 @@ namespace FTDI { * be broken so that the display width is less than w. The line will also * be broken after a '\n'. Returns the display width of the line. */ - static uint16_t find_line_break(const FontMetrics &utf8_fm, const CLCD::FontMetrics &clcd_fm, const uint16_t w, const char *str, const char *&end, bool use_utf8) { - const char *p = str; - end = str; + static uint16_t find_line_break(const FontMetrics &utf8_fm, const CLCD::FontMetrics &clcd_fm, const uint16_t w, const char *start, const char *&end, bool use_utf8) { + const char *p = start; + end = start; uint16_t lw = 0, result = 0; for (;;) { const char *next = p; - utf8_char_t c = get_utf8_char_and_inc(next); + const utf8_char_t c = get_utf8_char_and_inc(next); // Decide whether to break the string at this location if (c == '\n' || c == '\0' || c == ' ') { end = p; result = lw; } if (c == '\n' || c == '\0') break; - // Now add the length of the current character to the tally. - lw += use_utf8 ? utf8_fm.get_char_width(c) : clcd_fm.char_widths[(uint8_t)c]; + // Measure the next character + const uint16_t cw = use_utf8 ? utf8_fm.get_char_width(c) : clcd_fm.char_widths[(uint8_t)c]; // Stop processing once string exceeds the display width - if (lw >= w) { - if (end == str) { - end = p; - result = lw; - } - break; - } + if (lw + cw > w) break; + // Now add the length of the current character to the tally. + lw += cw; p = next; } + if (end == start) { + end = p; + result = lw; + } return result; } @@ -66,12 +66,13 @@ namespace FTDI { const uint16_t wrap_width = width; width = height = 0; for (;;) { - uint16_t line_width = find_line_break(utf8_fm, clcd_fm, wrap_width, line_start, line_end, use_utf8); + const uint16_t line_width = find_line_break(utf8_fm, clcd_fm, wrap_width, line_start, line_end, use_utf8); + if (line_end == line_start) break; width = max(width, line_width); height += utf8_fm.get_height(); line_start = line_end; - if (line_start[0] == '\n' || line_start[0] == ' ') line_start++; - if (line_start[0] == '\0') break; + if (*line_start == '\n' || *line_start == ' ') line_start++; + if (*line_start == '\0') break; } } @@ -108,28 +109,25 @@ namespace FTDI { const char *line_start = str, *line_end; for (;;) { find_line_break(utf8_fm, clcd_fm, w, line_start, line_end, use_utf8); + if (line_end == line_start) break; const size_t line_len = line_end - line_start; if (line_len) { - char line[line_len + 1]; - strncpy(line, line_start, line_len); - line[line_len] = 0; - #if ENABLED(TOUCH_UI_USE_UTF8) - if (use_utf8) { - draw_utf8_text(cmd, x + dx, y + dy, line, utf8_fm.fs, options & ~(OPT_CENTERY | OPT_BOTTOMY)); - } else + if (use_utf8) + draw_utf8_text(cmd, x + dx, y + dy, line_start, utf8_fm.fs, options & ~(OPT_CENTERY | OPT_BOTTOMY), line_len); + else #endif { cmd.CLCD::CommandFifo::text(x + dx, y + dy, font, options & ~(OPT_CENTERY | OPT_BOTTOMY)); - cmd.CLCD::CommandFifo::str(line); + cmd.CLCD::CommandFifo::str(line_start, line_len); } } y += utf8_fm.get_height(); line_start = line_end; - if (line_start[0] == '\n' || line_start[0] == ' ') line_start++; - if (line_start[0] == '\0') break; + if (*line_start == '\n' || *line_start == ' ') line_start++; + if (*line_start == '\0') break; } } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp index 55dd496e1c..2bb44e81d0 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp @@ -95,9 +95,9 @@ * fs - A scaling object used to specify the font size. */ - static uint16_t render_utf8_text(CommandProcessor* cmd, int x, int y, const char *str, font_size_t fs) { + static uint16_t render_utf8_text(CommandProcessor* cmd, int x, int y, const char *str, font_size_t fs, size_t maxlen=SIZE_MAX) { const int start_x = x; - while (*str) { + while (*str && maxlen--) { const utf8_char_t c = get_utf8_char_and_inc(str); #ifdef TOUCH_UI_UTF8_CYRILLIC_CHARSET CyrillicCharSet::render_glyph(cmd, x, y, fs, c) || @@ -185,8 +185,8 @@ * Returns: A width in pixels */ - uint16_t FTDI::get_utf8_text_width(const char *str, font_size_t fs) { - return render_utf8_text(nullptr, 0, 0, str, fs); + uint16_t FTDI::get_utf8_text_width(const char *str, font_size_t fs, size_t maxlen) { + return render_utf8_text(nullptr, 0, 0, str, fs, maxlen); } uint16_t FTDI::get_utf8_text_width(progmem_str pstr, font_size_t fs) { @@ -210,9 +210,10 @@ * * options - Text alignment options (i.e. OPT_CENTERX, OPT_CENTERY, OPT_CENTER or OPT_RIGHTX) * + * maxlen - Maximum characters to draw */ - void FTDI::draw_utf8_text(CommandProcessor& cmd, int x, int y, const char *str, font_size_t fs, uint16_t options) { + void FTDI::draw_utf8_text(CommandProcessor& cmd, int x, int y, const char *str, font_size_t fs, uint16_t options, size_t maxlen) { cmd.cmd(SAVE_CONTEXT()); cmd.cmd(BITMAP_TRANSFORM_A(fs.get_coefficient())); cmd.cmd(BITMAP_TRANSFORM_E(fs.get_coefficient())); @@ -220,14 +221,14 @@ // Apply alignment options if (options & OPT_CENTERX) - x -= get_utf8_text_width(str, fs) / 2; + x -= get_utf8_text_width(str, fs, maxlen) / 2; else if (options & OPT_RIGHTX) - x -= get_utf8_text_width(str, fs); + x -= get_utf8_text_width(str, fs, maxlen); if (options & OPT_CENTERY) y -= fs.get_height()/2; // Render the text - render_utf8_text(&cmd, x, y, str, fs); + render_utf8_text(&cmd, x, y, str, fs, maxlen); cmd.cmd(RESTORE_CONTEXT()); } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h index 5bb87d9684..3ca6dfd563 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h @@ -67,10 +67,10 @@ namespace FTDI { uint16_t get_utf8_char_width(utf8_char_t, font_size_t); uint16_t get_utf8_text_width(progmem_str, font_size_t); - uint16_t get_utf8_text_width(const char *, font_size_t); + uint16_t get_utf8_text_width(const char *, font_size_t, size_t maxlen=SIZE_MAX); void draw_utf8_text(CommandProcessor&, int x, int y, progmem_str, font_size_t, uint16_t options = 0); - void draw_utf8_text(CommandProcessor&, int x, int y, const char *, font_size_t, uint16_t options = 0); + void draw_utf8_text(CommandProcessor&, int x, int y, const char *, font_size_t, uint16_t options = 0, size_t maxlen=SIZE_MAX); // Similar to CLCD::FontMetrics, but can be used with UTF8 encoded strings. diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp index 68e50c90ac..ad6c9d4622 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp @@ -76,7 +76,9 @@ void AboutScreen::onRedraw(draw_mode_t) { #endif , OPT_CENTER, font_xlarge ); - cmd.tag(3); + #if BOTH(TOUCH_UI_DEVELOPER_MENU, FTDI_DEVELOPER_MENU) + cmd.tag(3); + #endif draw_text_box(cmd, FW_VERS_POS, #ifdef TOUCH_UI_VERSION F(TOUCH_UI_VERSION) @@ -89,7 +91,7 @@ void AboutScreen::onRedraw(draw_mode_t) { draw_text_box(cmd, LICENSE_POS, GET_TEXT_F(MSG_LICENSE), OPT_CENTER, font_tiny); cmd.font(font_medium); - #if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) + #if BOTH(PRINTCOUNTER, FTDI_STATISTICS_SCREEN) cmd.colors(normal_btn) .tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU)); #endif @@ -100,10 +102,10 @@ void AboutScreen::onRedraw(draw_mode_t) { bool AboutScreen::onTouchEnd(uint8_t tag) { switch (tag) { case 1: GOTO_PREVIOUS(); break; - #if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) + #if BOTH(PRINTCOUNTER, FTDI_STATISTICS_SCREEN) case 2: GOTO_SCREEN(StatisticsScreen); break; #endif - #if ENABLED(TOUCH_UI_DEVELOPER_MENU) && defined(FTDI_DEVELOPER_MENU) + #if BOTH(TOUCH_UI_DEVELOPER_MENU, FTDI_DEVELOPER_MENU) case 3: GOTO_SCREEN(DeveloperMenu); break; #endif default: return false; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.cpp index c10d372743..8c06fa9a9e 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.cpp @@ -53,17 +53,12 @@ bool ConfirmUserRequestAlertBox::onTouchEnd(uint8_t tag) { } } -void ConfirmUserRequestAlertBox::onIdle() { - if (!ExtUI::awaitingUserConfirm()) { - hide(); - } -} - void ConfirmUserRequestAlertBox::show(const char *msg) { drawMessage(msg); storeBackground(); screen_data.AlertDialogBox.isError = false; - GOTO_SCREEN(ConfirmUserRequestAlertBox); + if (!AT_SCREEN(ConfirmUserRequestAlertBox)) + GOTO_SCREEN(ConfirmUserRequestAlertBox); } void ConfirmUserRequestAlertBox::hide() { diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.h index d9a6c4a4fe..f83b1a24f5 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.h @@ -31,5 +31,4 @@ class ConfirmUserRequestAlertBox : public AlertDialogBox { static bool onTouchEnd(uint8_t); static void hide(); static void show(const char*); - static void onIdle(); };