From 100a8e3b332839f1f31a84d52352351c1b5f3e73 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 24 Jan 2023 11:57:25 +0100 Subject: [PATCH] Dynamic characters initial Fix more hardcoded characters Finally optimize the lcd printf with custom characters FontGen.py script Add arguments and action Fix build Fix conflicts --- Firmware/Fonts/FontGen.py | 92 ++++++++++++++++ Firmware/Fonts/FontTable.h | 10 ++ Firmware/Fonts/Font_CZ.lcd | 40 +++++++ Firmware/Fonts/Font_DE.lcd | 40 +++++++ Firmware/Fonts/Font_ES.lcd | 40 +++++++ Firmware/Fonts/Font_FR.lcd | 40 +++++++ Firmware/Fonts/Font_IT.lcd | 40 +++++++ Firmware/Fonts/Font_PL.lcd | 40 +++++++ Firmware/Fonts/Font_RO.lcd | 40 +++++++ Firmware/Fonts/Font_TR.lcd | 16 +++ Firmware/Fonts/Prusa.lcd | 104 ++++++++++++++++++ Firmware/lcd.cpp | 209 +++++++++--------------------------- Firmware/lcd.h | 28 ++--- Firmware/mmu2_reporting.cpp | 3 - Firmware/ultralcd.cpp | 44 ++++---- lang/lang-check.py | 4 +- 16 files changed, 594 insertions(+), 196 deletions(-) create mode 100644 Firmware/Fonts/FontGen.py create mode 100644 Firmware/Fonts/FontTable.h create mode 100644 Firmware/Fonts/Font_CZ.lcd create mode 100644 Firmware/Fonts/Font_DE.lcd create mode 100644 Firmware/Fonts/Font_ES.lcd create mode 100644 Firmware/Fonts/Font_FR.lcd create mode 100644 Firmware/Fonts/Font_IT.lcd create mode 100644 Firmware/Fonts/Font_PL.lcd create mode 100644 Firmware/Fonts/Font_RO.lcd create mode 100644 Firmware/Fonts/Font_TR.lcd create mode 100644 Firmware/Fonts/Prusa.lcd diff --git a/Firmware/Fonts/FontGen.py b/Firmware/Fonts/FontGen.py new file mode 100644 index 000000000..a809dd59d --- /dev/null +++ b/Firmware/Fonts/FontGen.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +import argparse +from traceback import print_exc +import xml.etree.ElementTree as ET +import os +import sys + +class CustomCharacter: + def __init__(self, utf, default, alternate = None): + self.utf = utf + self.default = default + self.alternate = alternate + +fontTable = [ +# custom characters: + CustomCharacter('πŸ„·', 0x80, 'H'), + CustomCharacter('Β°', 0x81, '\\xdf'), + CustomCharacter('🌑', 0x82, 'h'), + CustomCharacter('⬏', 0x83, '^'), + CustomCharacter('πŸ—˜', 0x84, '\\xf3'), + CustomCharacter('πŸ—€', 0x85, '\\xdb'), + CustomCharacter('Β»', 0x86, '>'), + CustomCharacter('πŸ•‘', 0x87, '\\xe5'), + CustomCharacter('↑', 0x88, '\\x7e'), + CustomCharacter('βœ”', 0x89, '\\x7e'), + +# from the default character set: + CustomCharacter('Γ€', 0xe1), + CustomCharacter('ΞΌ', 0xe4), + CustomCharacter('ΓΆ', 0xef), + CustomCharacter('ΓΌ', 0xf5), +] + +def generateLineInTable(index, chars): + pixels = chars[index]["PIXELS"].split(',') + rows = [] + for i in range(8): + rows.append(0) + for j in range(5): + rows[i] |= (1 << (5 - j - 1)) if pixels[j * 8 + i] == "0" else 0 + line = "{{" + for r in rows: + line += f"0x{r:02X}, " + line += f"}}, '{fontTable[index].alternate}'}}, // '{fontTable[index].utf}'" + return line + +def generateFont(): + tree = ET.parse(os.path.join(sys.path[0], "Prusa.lcd")) + root = tree.getroot() + + CharList = [Char.attrib for Char in root.iter("CHAR")] + + f = open(os.path.join(sys.path[0], "FontTable.h"), "w") + for x in range(len(fontTable)): + if fontTable[x].default >= 0xE0: + continue + f.write(generateLineInTable(x, CharList) + '\n') + f.close() + +def utfToLCD(infile, outfile): + return + +def lcdToUTF(infile, outfile): + return + +def main(): + parser = argparse.ArgumentParser(description = "Layer between the unicode and the LCD") + parser.add_argument("action", type = str, nargs = '?', default = "generateFont", + help = "What the script should do: (generateFont|utfToLCD|lcdToUTF)") + parser.add_argument('infile', nargs = '?', type = argparse.FileType('r'), default = sys.stdin) + parser.add_argument('outfile', nargs = '?', type = argparse.FileType('w'), default = sys.stdout) + args = parser.parse_args() + try: + if args.action == "generateFont": + generateFont() + elif args.action == "utfToLCD": + utfToLCD(args.infile, args.outfile) + elif args.action == "lcdToUTF": + lcdToUTF(args.infile, args.outfile) + else: + print("invalid action") + return 1 + # parse_txt(args.lang, args.no_warning, args.warn_empty) + return 0 + except Exception as exc: + print_exc() + parser.error("%s" % exc) + return 1 + +if __name__ == "__main__": + exit(main()) diff --git a/Firmware/Fonts/FontTable.h b/Firmware/Fonts/FontTable.h new file mode 100644 index 000000000..9e966851a --- /dev/null +++ b/Firmware/Fonts/FontTable.h @@ -0,0 +1,10 @@ +{{0x00, 0x1F, 0x15, 0x11, 0x15, 0x1F, 0x00, 0x00, }, 'H'}, // 'πŸ„·' +{{0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00, }, '\xdf'}, // 'Β°' +{{0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x11, 0x0E, }, 'h'}, // '🌑' +{{0x04, 0x0E, 0x1F, 0x04, 0x1C, 0x00, 0x00, 0x00, }, '^'}, // '⬏' +{{0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0C, 0x00, }, '\xf3'}, // 'πŸ—˜' +{{0x00, 0x1C, 0x1F, 0x11, 0x11, 0x1F, 0x00, 0x00, }, '\xdb'}, // 'πŸ—€' +{{0x00, 0x04, 0x12, 0x09, 0x12, 0x04, 0x00, 0x00, }, '>'}, // 'Β»' +{{0x00, 0x0E, 0x13, 0x15, 0x11, 0x0E, 0x00, 0x00, }, '\xe5'}, // 'πŸ•‘' +{{0x00, 0x00, 0x11, 0x0A, 0x04, 0x11, 0x0A, 0x04, }, '\x7e'}, // '↑' +{{0x00, 0x01, 0x03, 0x16, 0x1C, 0x08, 0x00, 0x00, }, '\x7e'}, // 'βœ”' diff --git a/Firmware/Fonts/Font_CZ.lcd b/Firmware/Fonts/Font_CZ.lcd new file mode 100644 index 000000000..22751d30b --- /dev/null +++ b/Firmware/Fonts/Font_CZ.lcd @@ -0,0 +1,40 @@ + + + CZ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_DE.lcd b/Firmware/Fonts/Font_DE.lcd new file mode 100644 index 000000000..453232ac4 --- /dev/null +++ b/Firmware/Fonts/Font_DE.lcd @@ -0,0 +1,40 @@ + + + DE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_ES.lcd b/Firmware/Fonts/Font_ES.lcd new file mode 100644 index 000000000..fc132ab2a --- /dev/null +++ b/Firmware/Fonts/Font_ES.lcd @@ -0,0 +1,40 @@ + + + ES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_FR.lcd b/Firmware/Fonts/Font_FR.lcd new file mode 100644 index 000000000..fd07b6f23 --- /dev/null +++ b/Firmware/Fonts/Font_FR.lcd @@ -0,0 +1,40 @@ + + + FR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_IT.lcd b/Firmware/Fonts/Font_IT.lcd new file mode 100644 index 000000000..60815e2ad --- /dev/null +++ b/Firmware/Fonts/Font_IT.lcd @@ -0,0 +1,40 @@ + + + IT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_PL.lcd b/Firmware/Fonts/Font_PL.lcd new file mode 100644 index 000000000..95fdfb59c --- /dev/null +++ b/Firmware/Fonts/Font_PL.lcd @@ -0,0 +1,40 @@ + + + PL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_RO.lcd b/Firmware/Fonts/Font_RO.lcd new file mode 100644 index 000000000..eb5e5dcbd --- /dev/null +++ b/Firmware/Fonts/Font_RO.lcd @@ -0,0 +1,40 @@ + + + RO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Font_TR.lcd b/Firmware/Fonts/Font_TR.lcd new file mode 100644 index 000000000..2a2a1a71e --- /dev/null +++ b/Firmware/Fonts/Font_TR.lcd @@ -0,0 +1,16 @@ + + + TR + + + + + + + + + + + + + diff --git a/Firmware/Fonts/Prusa.lcd b/Firmware/Fonts/Prusa.lcd new file mode 100644 index 000000000..dab031c80 --- /dev/null +++ b/Firmware/Fonts/Prusa.lcd @@ -0,0 +1,104 @@ + + + Prusa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 204ba73e9..9d1dd37bf 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -75,11 +75,15 @@ uint8_t lcd_displaycontrol = 0; uint8_t lcd_displaymode = 0; uint8_t lcd_currline; +uint8_t lcd_ddram_address; // no need for preventing ddram overflow #ifdef VT100 uint8_t lcd_escape[8]; #endif +uint8_t lcd_custom_characters[8] = {0}; +uint8_t lcd_custom_index = 0; + static void lcd_display(void); #if 0 @@ -96,6 +100,8 @@ static void lcd_autoscroll(void); static void lcd_no_autoscroll(void); #endif +static void lcd_print_custom(uint8_t c); + #ifdef VT100 void lcd_escape_write(uint8_t chr); #endif @@ -144,24 +150,32 @@ static void lcd_command(uint8_t value, uint16_t duration = LCD_DEFAULT_DELAY) static void lcd_write(uint8_t value) { - if (value == '\n') - { + if (value == '\n') { if (lcd_currline > 3) lcd_currline = -1; lcd_set_cursor(0, lcd_currline + 1); // LF - return; + } + else if ((value >= 0x80) && (value <= 0xDF)) { + lcd_print_custom(value); } #ifdef VT100 - if (lcd_escape[0] || (value == 0x1b)){ + else if (lcd_escape[0] || (value == '\e')) { lcd_escape_write(value); - return; } #endif - lcd_send(value, HIGH); + else { + lcd_send(value, HIGH); + lcd_ddram_address++; // no need for preventing ddram overflow + } } static void lcd_begin(uint8_t clear) { lcd_currline = 0; + lcd_ddram_address = 0; + lcd_custom_index = 0; + + lcd_custom_index = 0; + memset(lcd_custom_characters, 0, sizeof(lcd_custom_characters)); lcd_send(LCD_FUNCTIONSET | LCD_8BITMODE, LOW | LCD_HALF_FLAG, 4500); // wait min 4.1ms // second try @@ -225,25 +239,27 @@ void lcd_init(void) void lcd_refresh(void) { lcd_begin(1); - lcd_set_custom_characters(); } void lcd_refresh_noclear(void) { lcd_begin(0); - lcd_set_custom_characters(); } void lcd_clear(void) { lcd_command(LCD_CLEARDISPLAY, 1600); // clear display, set cursor position to zero lcd_currline = 0; + lcd_ddram_address = 0; + lcd_custom_index = 0; } void lcd_home(void) { lcd_command(LCD_RETURNHOME, 1600); // set cursor position to zero lcd_currline = 0; + lcd_ddram_address = 0; + lcd_custom_index = 0; } // Turn the display on/off (quickly) @@ -348,7 +364,9 @@ static uint8_t __attribute__((noinline)) lcd_get_row_offset(uint8_t row) void lcd_set_cursor(uint8_t col, uint8_t row) { lcd_set_current_row(row); - lcd_command(LCD_SETDDRAMADDR | (col + lcd_get_row_offset(lcd_currline))); + uint8_t addr = col + lcd_get_row_offset(lcd_currline); + lcd_ddram_address = addr; + lcd_command(LCD_SETDDRAMADDR | addr); } void lcd_set_cursor_column(uint8_t col) @@ -364,6 +382,7 @@ void lcd_createChar_P(uint8_t location, const uint8_t* charmap) lcd_command(LCD_SETCGRAMADDR | (location << 3)); for (uint8_t i = 0; i < 8; i++) lcd_send(pgm_read_byte(&charmap[i]), HIGH); + lcd_command(LCD_SETDDRAMADDR | lcd_ddram_address); // no need for masking the address } #ifdef VT100 @@ -426,7 +445,7 @@ void lcd_escape_write(uint8_t chr) break; case '2': if (chr == 'J') // escape = "\x1b[2J" - { lcd_clear(); lcd_currline = 0; break; } // EraseScreen + { lcd_clear(); break; } // EraseScreen default: if (e_2_is_num && // escape = "\x1b[%1d" ((chr == ';') || // escape = "\x1b[%1d;" @@ -809,151 +828,29 @@ void lcd_buttons_update(void) //////////////////////////////////////////////////////////////////////////////// // Custom character data -const uint8_t lcd_chardata_bedTemp[8] PROGMEM = { - 0b00000, - 0b11111, - 0b10101, - 0b10001, - 0b10101, - 0b11111, - 0b00000, - 0b00000}; //thanks Sonny Mounicou +const CustomCharacter Font[] PROGMEM = { +#include "Fonts/FontTable.h" +}; -const uint8_t lcd_chardata_degree[8] PROGMEM = { - 0b01100, - 0b10010, - 0b10010, - 0b01100, - 0b00000, - 0b00000, - 0b00000, - 0b00000}; - -const uint8_t lcd_chardata_thermometer[8] PROGMEM = { - 0b00100, - 0b01010, - 0b01010, - 0b01010, - 0b01010, - 0b10001, - 0b10001, - 0b01110}; - -const uint8_t lcd_chardata_uplevel[8] PROGMEM = { - 0b00100, - 0b01110, - 0b11111, - 0b00100, - 0b11100, - 0b00000, - 0b00000, - 0b00000}; //thanks joris - -const uint8_t lcd_chardata_refresh[8] PROGMEM = { - 0b00000, - 0b00110, - 0b11001, - 0b11000, - 0b00011, - 0b10011, - 0b01100, - 0b00000}; //thanks joris - -const uint8_t lcd_chardata_folder[8] PROGMEM = { - 0b00000, - 0b11100, - 0b11111, - 0b10001, - 0b10001, - 0b11111, - 0b00000, - 0b00000}; //thanks joris - -/*const uint8_t lcd_chardata_feedrate[8] PROGMEM = { - 0b11100, - 0b10000, - 0b11000, - 0b10111, - 0b00101, - 0b00110, - 0b00101, - 0b00000};*/ //thanks Sonny Mounicou - -/*const uint8_t lcd_chardata_feedrate[8] PROGMEM = { - 0b11100, - 0b10100, - 0b11000, - 0b10100, - 0b00000, - 0b00111, - 0b00010, - 0b00010};*/ - -/*const uint8_t lcd_chardata_feedrate[8] PROGMEM = { - 0b01100, - 0b10011, - 0b00000, - 0b01100, - 0b10011, - 0b00000, - 0b01100, - 0b10011};*/ - -const uint8_t lcd_chardata_feedrate[8] PROGMEM = { - 0b00000, - 0b00100, - 0b10010, - 0b01001, - 0b10010, - 0b00100, - 0b00000, - 0b00000}; - -const uint8_t lcd_chardata_clock[8] PROGMEM = { - 0b00000, - 0b01110, - 0b10011, - 0b10101, - 0b10001, - 0b01110, - 0b00000, - 0b00000}; //thanks Sonny Mounicou - -void lcd_set_custom_characters(void) -{ - lcd_createChar_P(LCD_STR_BEDTEMP[0], lcd_chardata_bedTemp); - lcd_createChar_P(LCD_STR_DEGREE[0], lcd_chardata_degree); - lcd_createChar_P(LCD_STR_THERMOMETER[0], lcd_chardata_thermometer); - lcd_createChar_P(LCD_STR_UPLEVEL[0], lcd_chardata_uplevel); - lcd_createChar_P(LCD_STR_REFRESH[0], lcd_chardata_refresh); - lcd_createChar_P(LCD_STR_FOLDER[0], lcd_chardata_folder); - lcd_createChar_P(LCD_STR_FEEDRATE[0], lcd_chardata_feedrate); - lcd_createChar_P(LCD_STR_CLOCK[0], lcd_chardata_clock); +static void lcd_print_custom(uint8_t c) { + if (lcd_custom_index >= 8) { //ran out of custom characters. Use the alternate character. + lcd_send(pgm_read_byte(&Font[c - 0x80].alternate), HIGH); + lcd_ddram_address++; // no need for preventing ddram overflow + return; + } + + // check if we already have the character in the lcd memory + for (uint8_t i = 0; i < 8; i++) { + if (lcd_custom_characters[i] == c) { + lcd_send(i, HIGH); + lcd_ddram_address++; // no need for preventing ddram overflow + return; + } + } + // character not in memory. Add it + lcd_createChar_P(lcd_custom_index, Font[c - 0x80].data); + lcd_custom_characters[lcd_custom_index] = c; + lcd_send(lcd_custom_index, HIGH); + lcd_ddram_address++; // no need for preventing ddram overflow + lcd_custom_index++; } - -const uint8_t lcd_chardata_arr2down[8] PROGMEM = { - 0b00000, - 0b00000, - 0b10001, - 0b01010, - 0b00100, - 0b10001, - 0b01010, - 0b00100}; - -const uint8_t lcd_chardata_confirm[8] PROGMEM = { - 0b00000, - 0b00001, - 0b00011, - 0b10110, - 0b11100, - 0b01000, - 0b00000, - 0b00000}; - -void lcd_set_custom_characters_nextpage(void) -{ - lcd_createChar_P(LCD_STR_ARROW_2_DOWN[0], lcd_chardata_arr2down); - lcd_createChar_P(LCD_STR_CONFIRM[0], lcd_chardata_confirm); -} - diff --git a/Firmware/lcd.h b/Firmware/lcd.h index da509de07..b5adcaa4d 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -171,21 +171,25 @@ private: //////////////////////////////////// //Custom characters defined in the first 8 characters of the LCD -#define LCD_STR_BEDTEMP "\x00" -#define LCD_STR_DEGREE "\x01" -#define LCD_STR_THERMOMETER "\x02" -#define LCD_STR_UPLEVEL "\x03" -#define LCD_STR_REFRESH "\x04" -#define LCD_STR_FOLDER "\x05" -#define LCD_STR_FEEDRATE "\x06" -#define LCD_STR_ARROW_2_DOWN "\x06" -#define LCD_STR_CLOCK "\x07" -#define LCD_STR_CONFIRM "\x07" #define LCD_STR_ARROW_RIGHT "\x7E" //from the default character set +#define LCD_STR_BEDTEMP "\x80" +#define LCD_STR_DEGREE "\x81" +#define LCD_STR_THERMOMETER "\x82" +#define LCD_STR_UPLEVEL "\x83" +#define LCD_STR_REFRESH "\x84" +#define LCD_STR_FOLDER "\x85" +#define LCD_STR_FEEDRATE "\x86" +#define LCD_STR_CLOCK "\x87" +#define LCD_STR_ARROW_2_DOWN "\x88" +#define LCD_STR_CONFIRM "\x89" #define LCD_STR_SOLID_BLOCK "\xFF" //from the default character set -extern void lcd_set_custom_characters(void); -extern void lcd_set_custom_characters_nextpage(void); +struct CustomCharacter { + const uint8_t data[8]; + const char alternate; +}; + +extern uint8_t lcd_custom_index; //! @brief Consume click and longpress event inline void lcd_consume_click() diff --git a/Firmware/mmu2_reporting.cpp b/Firmware/mmu2_reporting.cpp index 0efe3341f..e2ced92f1 100644 --- a/Firmware/mmu2_reporting.cpp +++ b/Firmware/mmu2_reporting.cpp @@ -71,7 +71,6 @@ static void ReportErrorHookStaticRender(uint8_t ei) { two_choices = true; } - lcd_set_custom_characters_nextpage(); lcd_update_enable(false); lcd_clear(); @@ -261,7 +260,6 @@ void ReportErrorHook(CommandInProgress /*cip*/, ErrorCode ec, uint8_t /*es*/) { break; case 2: // Exit error screen and enable lcd updates - lcd_set_custom_characters(); lcd_update_enable(true); lcd_return_to_status(); sound_wait_for_user_reset(); @@ -275,7 +273,6 @@ void ReportErrorHook(CommandInProgress /*cip*/, ErrorCode ec, uint8_t /*es*/) { return; // Always return to loop() to let MMU trigger a call to ReportErrorHook again break; case (uint8_t)ReportErrorHookStates::DISMISS_ERROR_SCREEN: - lcd_set_custom_characters(); lcd_update_enable(true); lcd_return_to_status(); sound_wait_for_user_reset(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 15a5bc5fd..a93678cc1 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -313,7 +313,7 @@ static void menu_item_sdfile(const char* str_fn, char* str_fnl) // Print temperature (nozzle/bed) (9 chars total) void lcdui_print_temp(char type, int val_current, int val_target) { - int chars = lcd_printf_P(_N("%c%3d/%d%c"), type, val_current, val_target, LCD_STR_DEGREE[0]); + int chars = lcd_printf_P(_N("%c%3d/%d" LCD_STR_DEGREE), type, val_current, val_target); lcd_space(9 - chars); } @@ -352,7 +352,7 @@ void lcdui_print_planner_diag(void) // Print feedrate (8 chars total) void lcdui_print_feedrate(void) { - int chars = lcd_printf_P(_N("%c%3d%%"), LCD_STR_FEEDRATE[0], feedmultiply); + int chars = lcd_printf_P(_N(LCD_STR_FEEDRATE "%3d%%"), feedmultiply); lcd_space(8 - chars); } @@ -487,12 +487,12 @@ void lcdui_print_time(void) } if (print_t < 6000) //time<100h - chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); + chars = lcd_printf_P(_N(LCD_STR_CLOCK "%02u:%02u%c%c"), print_t / 60, print_t % 60, suff, suff_doubt); else //time>=100h - chars = lcd_printf_P(_N("%c%3uh %c%c"), LCD_STR_CLOCK[0], print_t / 60, suff, suff_doubt); + chars = lcd_printf_P(_N(LCD_STR_CLOCK "%3uh %c%c"), print_t / 60, suff, suff_doubt); } else - chars = lcd_printf_P(_N("%c--:-- "), LCD_STR_CLOCK[0]); + chars = lcd_printf_P(_N(LCD_STR_CLOCK "--:-- ")); lcd_space(8 - chars); } @@ -627,8 +627,7 @@ void lcdui_print_status_line(void) { //! @endcode void lcdui_print_status_screen(void) { - - lcd_set_cursor(0, 0); //line 0 + lcd_home(); //line 0 //Print the hotend temperature (9 chars total) lcdui_print_temp(LCD_STR_THERMOMETER[0], (int)(degHotend(0) + 0.5), (int)(degTargetHotend(0) + 0.5)); @@ -1338,7 +1337,7 @@ static void lcd_menu_temperatures_line(const char *ipgmLabel, int value){ static const size_t maxChars = 15; char tmp[maxChars]; pgmtext_with_colon(ipgmLabel, tmp, maxChars); - lcd_printf_P(PSTR(" %s%3d\x01 \n"), tmp, value); // no need to add -14.14 to string alignment + lcd_printf_P(PSTR(" %s%3d" LCD_STR_DEGREE " \n"), tmp, value); // no need to add -14.14 to string alignment } //! @brief Show Temperatures @@ -2480,8 +2479,8 @@ static void lcd_menu_xyz_skew() lcd_printf_P(_N( "%-14.14S:\n" "%S\n" - "%-14.14S:%3.2f\x01\n" - "%-14.14S:%3.2f\x01" + "%-14.14S:%3.2f" LCD_STR_DEGREE "\n" + "%-14.14S:%3.2f" LCD_STR_DEGREE ), _i("Measured skew"), ////MSG_MEASURED_SKEW c=14 STR_SEPARATOR, @@ -2490,7 +2489,7 @@ static void lcd_menu_xyz_skew() ); lcd_set_cursor(15, 0); if (angleDiff < 100){ - lcd_printf_P(_N("%3.2f\x01"), _deg(angleDiff)); + lcd_printf_P(_N("%3.2f" LCD_STR_DEGREE), _deg(angleDiff)); } else { lcd_puts_P(_T(MSG_NA)); } @@ -2510,6 +2509,7 @@ static void lcd_menu_xyz_skew() //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. static void lcd_menu_xyz_offset() { + lcd_home(); lcd_puts_at_P(0, 0, _i("[0;0] point offset"));////MSG_MEASURED_OFFSET c=20 lcd_puts_at_P(0, 1, STR_SEPARATOR); @@ -2596,7 +2596,7 @@ static void lcd_babystep_z() { SheetFormatBuffer buffer; menu_format_sheet_E(EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))], buffer); - lcd_set_cursor(0, 0); + lcd_home(); lcd_print(buffer.c); lcd_set_cursor(0, 1); menu_draw_float13(_i("Adjusting Z"), _md->babystepMemMMZ); ////MSG_BABYSTEPPING_Z c=13 @@ -2861,6 +2861,7 @@ static inline bool pgm_is_interpunction(const char *c_addr) */ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg) { + lcd_home(); const char *msgend = msg; bool multi_screen = false; for (uint8_t row = 0; row < LCD_HEIGHT; ++ row) { @@ -2906,8 +2907,6 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg) } if (multi_screen) { - // Display the "next screen" indicator character. - lcd_set_custom_characters_nextpage(); // Display the double down arrow. lcd_putc_at(19, 3, LCD_STR_ARROW_2_DOWN[0]); } @@ -2935,7 +2934,6 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg) LcdUpdateDisabler lcdUpdateDisabler; const char *msg_next = lcd_display_message_fullscreen_P(msg); bool multi_screen = msg_next != NULL; - lcd_set_custom_characters_nextpage(); lcd_consume_click(); KEEPALIVE_STATE(PAUSED_FOR_USER); // Until confirmed by a button click. @@ -2950,7 +2948,6 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg) if (lcd_clicked()) { if (msg_next == NULL) { KEEPALIVE_STATE(IN_HANDLER); - lcd_set_custom_characters(); return; } else { @@ -3039,7 +3036,6 @@ uint8_t lcd_show_multiscreen_message_with_choices_and_wait_P( ) { const char *msg_next = msg ? lcd_display_message_fullscreen_P(msg) : NULL; bool multi_screen = msg_next != NULL; - lcd_set_custom_characters_nextpage(); // Initial status/prompt on single-screen messages uint8_t current_selection = default_selection; @@ -3102,7 +3098,6 @@ uint8_t lcd_show_multiscreen_message_with_choices_and_wait_P( } exit: KEEPALIVE_STATE(IN_HANDLER); - lcd_set_custom_characters(); // Enable LCD updates again. We may not call lcd_update_enable(true) // because it may create a recursion scenario when the caller of lcd_show_multiscreen_message_with_choices_and_wait_P // is a submenu lcd_update_enable(true) will cause another call to the submenu immediately @@ -3214,6 +3209,7 @@ void lcd_temp_cal_show_result(bool result) { #ifndef TMC2130 static void lcd_show_end_stops() { + lcd_home(); lcd_puts_at_P(0, 0, (PSTR("End stops diag"))); lcd_puts_at_P(0, 1, (READ(X_MIN_PIN) ^ (bool)X_MIN_ENDSTOP_INVERTING) ? (PSTR("X1")) : (PSTR("X0"))); lcd_puts_at_P(0, 2, (READ(Y_MIN_PIN) ^ (bool)Y_MIN_ENDSTOP_INVERTING) ? (PSTR("Y1")) : (PSTR("Y0"))); @@ -3587,8 +3583,8 @@ void lcd_first_layer_calibration_reset() char sheet_name[sizeof(Sheet::name)]; eeprom_read_block(sheet_name, &EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].name, sizeof(Sheet::name)); - lcd_set_cursor(0, 0); - float offset = static_cast(eeprom_read_word(reinterpret_cast(&EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)))/cs.axis_steps_per_mm[Z_AXIS]; + lcd_home(); + float offset = static_cast(eeprom_read_word(reinterpret_cast(&EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)))/cs.axis_steps_per_unit[Z_AXIS]; lcd_printf_P(_i("Sheet %.7s\nZ offset: %+1.3fmm\n%cContinue\n%cReset"),////MSG_SHEET_OFFSET c=20 r=4 sheet_name, offset, menuData->reset ? ' ' : '>', menuData->reset ? '>' : ' ');// \n denotes line break, %.7s is replaced by 7 character long sheet name, %+1.3f is replaced by 6 character long floating point number, %c is replaced by > or white space (one character) based on whether first or second option is selected. % denoted place holders can not be reordered. @@ -5059,7 +5055,7 @@ static void lcd_rename_sheet_menu() if (lcd_encoder > '\x7F') lcd_encoder = '\x7F'; menuData->name[menuData->selected] = lcd_encoder; - lcd_set_cursor(0,0); + lcd_home(); for (uint_least8_t i = 0; i < sizeof(Sheet::name); ++i) { lcd_putc(menuData->name[i]); @@ -6849,8 +6845,10 @@ static uint8_t lcd_selftest_screen(TestScreen screen, uint8_t _progress, uint8_t lcd_update_enable(false); const char _indicator = (_progress >= _progress_scale) ? '-' : '|'; - if (_clear) lcd_clear(); - lcd_set_cursor(0, 0); + if (_clear) + lcd_clear(); + else + lcd_home(); if (screen == TestScreen::ExtruderFan) lcd_puts_P(_T(MSG_SELFTEST_FAN)); if (screen == TestScreen::PrintFan) lcd_puts_P(_T(MSG_SELFTEST_FAN)); diff --git a/lang/lang-check.py b/lang/lang-check.py index 1c651b692..cafcfee17 100755 --- a/lang/lang-check.py +++ b/lang/lang-check.py @@ -134,10 +134,10 @@ def wrap_text(text, cols): return ret def ign_char_first(c): - return c.isalnum() or c in {'%', '?'} + return c.isalnum() or c in ['%', '?'] or c in [chr(c) for c in range(0x80, 0xE0)] def ign_char_last(c): - return c.isalnum() or c in {'.', "'"} + return c.isalnum() or c in ['.', '\''] or c in [chr(c) for c in range(0x80, 0xE0)] # Print_anyway is used to reduce code copypasta. # specifically, if we have all the info here to construct the "normal" message as well, it's done here