Fix incorrect UTF filename scrolling
This commit is contained in:
parent
37b56e09a3
commit
ca9f27dc62
4 changed files with 59 additions and 12 deletions
|
|
@ -461,8 +461,11 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
|
||||||
|
|
||||||
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
|
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
|
||||||
if (mark_as_selected(row, sel)) {
|
if (mark_as_selected(row, sel)) {
|
||||||
if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
|
uint8_t maxlen = LCD_WIDTH;
|
||||||
constexpr uint8_t maxlen = LCD_WIDTH - 1;
|
if (isDir) {
|
||||||
|
lcd_put_wchar(LCD_STR_FOLDER[0]);
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH);
|
const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH);
|
||||||
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
|
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
|
||||||
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
|
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,11 @@ int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if passed byte is first byte of UTF-8 char sequence */
|
||||||
|
static inline bool utf8_is_start_byte_of_char(const uint8_t b) {
|
||||||
|
return 0x80 != (b & 0xC0);
|
||||||
|
}
|
||||||
|
|
||||||
/* This function gets the character at the pstart position, interpreting UTF8 multibyte sequences
|
/* This function gets the character at the pstart position, interpreting UTF8 multibyte sequences
|
||||||
and returns the pointer to the next character */
|
and returns the pointer to the next character */
|
||||||
uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
|
uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
|
||||||
|
|
@ -131,8 +136,8 @@ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (0x80 == (0xC0 & valcur))
|
else if (!utf8_is_start_byte_of_char(valcur))
|
||||||
for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
|
for (; !utf8_is_start_byte_of_char(valcur); ) { p++; valcur = cb_read_byte(p); }
|
||||||
else
|
else
|
||||||
for (; 0xFC < (0xFE & valcur); ) { p++; valcur = cb_read_byte(p); }
|
for (; 0xFC < (0xFE & valcur); ) { p++; valcur = cb_read_byte(p); }
|
||||||
|
|
||||||
|
|
@ -143,12 +148,12 @@ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t
|
||||||
|
|
||||||
static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
|
static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
|
||||||
uint8_t cnt = 0;
|
uint8_t cnt = 0;
|
||||||
uint8_t *pnext = (uint8_t *)pstart;
|
uint8_t *p = (uint8_t *)pstart;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
wchar_t ch;
|
uint8_t b = cb_read_byte(p);
|
||||||
pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
|
if (!b) break;
|
||||||
if (!ch) break;
|
if (utf8_is_start_byte_of_char(b)) cnt++;
|
||||||
cnt++;
|
p++;
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
@ -160,3 +165,26 @@ uint8_t utf8_strlen(const char *pstart) {
|
||||||
uint8_t utf8_strlen_P(PGM_P pstart) {
|
uint8_t utf8_strlen_P(PGM_P pstart) {
|
||||||
return utf8_strlen_cb(pstart, read_byte_rom);
|
return utf8_strlen_cb(pstart, read_byte_rom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint8_t utf8_byte_pos_by_char_num_cb(const char *pstart, read_byte_cb_t cb_read_byte, const uint8_t charnum) {
|
||||||
|
uint8_t *p = (uint8_t *)pstart;
|
||||||
|
uint8_t char_idx = 0;
|
||||||
|
uint8_t byte_idx = 0;
|
||||||
|
for (;;) {
|
||||||
|
uint8_t b = cb_read_byte(p+byte_idx);
|
||||||
|
if (!b) return byte_idx; // Termination byte of string
|
||||||
|
if (utf8_is_start_byte_of_char(b)) {
|
||||||
|
char_idx++;
|
||||||
|
if (char_idx == charnum + 1) return byte_idx;
|
||||||
|
}
|
||||||
|
byte_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t utf8_byte_pos_by_char_num(const char *pstart, const uint8_t charnum) {
|
||||||
|
return utf8_byte_pos_by_char_num_cb(pstart, read_byte_ram, charnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t utf8_byte_pos_by_char_num_P(PGM_P pstart, const uint8_t charnum) {
|
||||||
|
return utf8_byte_pos_by_char_num_cb(pstart, read_byte_rom, charnum);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,3 +41,7 @@ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t
|
||||||
/* Returns length of string in CHARACTERS, NOT BYTES */
|
/* Returns length of string in CHARACTERS, NOT BYTES */
|
||||||
uint8_t utf8_strlen(const char *pstart);
|
uint8_t utf8_strlen(const char *pstart);
|
||||||
uint8_t utf8_strlen_P(PGM_P pstart);
|
uint8_t utf8_strlen_P(PGM_P pstart);
|
||||||
|
|
||||||
|
/* Returns start byte position of desired char number */
|
||||||
|
uint8_t utf8_byte_pos_by_char_num(const char *pstart, const uint8_t charnum);
|
||||||
|
uint8_t utf8_byte_pos_by_char_num_P(PGM_P pstart, const uint8_t charnum);
|
||||||
|
|
|
||||||
|
|
@ -208,10 +208,19 @@ millis_t MarlinUI::next_button_update_ms; // = 0
|
||||||
filename_scroll_pos = 0; // Reset scroll to the start
|
filename_scroll_pos = 0; // Reset scroll to the start
|
||||||
lcd_status_update_delay = 8; // Don't scroll right away
|
lcd_status_update_delay = 8; // Don't scroll right away
|
||||||
}
|
}
|
||||||
outstr += filename_scroll_pos;
|
#if ENABLED(UTF_FILENAME_SUPPORT)
|
||||||
|
// Advance byte position corresponding to filename_scroll_pos char position
|
||||||
|
outstr += utf8_byte_pos_by_char_num(outstr, filename_scroll_pos);
|
||||||
|
#else
|
||||||
|
outstr += filename_scroll_pos;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
|
#if ENABLED(UTF_FILENAME_SUPPORT)
|
||||||
|
theCard.longFilename[utf8_byte_pos_by_char_num(theCard.longFilename, maxlen)] = '\0'; // cutoff at screen edge
|
||||||
|
#else
|
||||||
|
theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return outstr;
|
return outstr;
|
||||||
|
|
@ -1007,7 +1016,10 @@ void MarlinUI::update() {
|
||||||
// cause a refresh to occur until all the text has scrolled into view.
|
// cause a refresh to occur until all the text has scrolled into view.
|
||||||
if (currentScreen == menu_media && !lcd_status_update_delay--) {
|
if (currentScreen == menu_media && !lcd_status_update_delay--) {
|
||||||
lcd_status_update_delay = 4;
|
lcd_status_update_delay = 4;
|
||||||
if (++filename_scroll_pos > filename_scroll_max) {
|
filename_scroll_pos++;
|
||||||
|
if (filename_scroll_pos == filename_scroll_max){
|
||||||
|
lcd_status_update_delay = 12;
|
||||||
|
} else if (filename_scroll_pos > filename_scroll_max) {
|
||||||
filename_scroll_pos = 0;
|
filename_scroll_pos = 0;
|
||||||
lcd_status_update_delay = 12;
|
lcd_status_update_delay = 12;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue