diff --git a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
index 1a1e7b1750009924b7ec1dd23b1c00b2caaa3c4c..96921ed755f2042e0c9f2e561a22f74bc4a62196 100644
--- a/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
+++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp
@@ -363,10 +363,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
       // Fits into,
       lcd_moveto(col, line);
       lcd_put_u8str_max_P(text, len);
-      while (slen < len) {
-        lcd_put_wchar(' ');
-        ++slen;
-      }
+      for (; slen < len; ++slen) lcd_put_wchar(' ');
       safe_delay(time);
     }
     else {
@@ -381,11 +378,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
         lcd_put_u8str_max_P(p, len);
 
         // Fill with spaces
-        uint8_t ix = slen - i;
-        while (ix < len) {
-          lcd_put_wchar(' ');
-          ++ix;
-        }
+        for (uint8_t ix = slen - i; ix < len; ++ix) lcd_put_wchar(' ');
 
         // Delay
         safe_delay(dly);
@@ -995,7 +988,7 @@ void MarlinUI::draw_status_screen() {
     lcd_moveto(0, row);
     lcd_put_wchar(sel ? pre_char : ' ');
     n -= lcd_put_u8str_max_P(pstr, n);
-    while (n--) lcd_put_wchar(' ');
+    for (; n; --n) lcd_put_wchar(' ');
     lcd_put_wchar(post_char);
   }
 
@@ -1005,7 +998,7 @@ void MarlinUI::draw_status_screen() {
     lcd_put_wchar(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
     n -= lcd_put_u8str_max_P(pstr, n);
     lcd_put_wchar(':');
-    while (n--) lcd_put_wchar(' ');
+    for (; n; --n) lcd_put_wchar(' ');
     if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data);
   }
 
@@ -1025,40 +1018,14 @@ void MarlinUI::draw_status_screen() {
   #if ENABLED(SDSUPPORT)
 
     void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
-      const char post_char = isDir ? LCD_STR_FOLDER[0] : ' ',
-                 sel_char = sel ? LCD_STR_ARROW_RIGHT[0] : ' ';
       UNUSED(pstr);
-      lcd_moveto(0, row);
-      lcd_put_wchar(sel_char);
-
-      uint8_t n = LCD_WIDTH - 2;
-      const char *outstr = theCard.longest_filename();
-      if (theCard.longFilename[0]) {
-        #if ENABLED(SCROLL_LONG_FILENAMES)
-          static uint8_t filename_scroll_hash;
-          if (sel) {
-            uint8_t name_hash = row;
-            for (uint8_t l = FILENAME_LENGTH; l--;)
-              name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ theCard.filename[l];  // rotate, xor
-            if (filename_scroll_hash != name_hash) {                            // If the hash changed...
-              filename_scroll_hash = name_hash;                                 // Save the new hash
-              ui.filename_scroll_max = MAX(0, utf8_strlen(theCard.longFilename) - n); // Update the scroll limit
-              ui.filename_scroll_pos = 0;                                       // Reset scroll to the start
-              ui.lcd_status_update_delay = 8;                                   // Don't scroll right away
-            }
-            outstr += ui.filename_scroll_pos;
-          }
-        #else
-          theCard.longFilename[n] = '\0'; // cutoff at screen edge
-        #endif
-      }
 
       lcd_moveto(0, row);
-      lcd_put_wchar(sel_char);
-      n -= lcd_put_u8str_max(outstr, n);
-
+      lcd_put_wchar(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
+      constexpr uint8_t maxlen = LCD_WIDTH - 2;
+      uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
       for (; n; --n) lcd_put_wchar(' ');
-      lcd_put_wchar(post_char);
+      lcd_put_wchar(isDir ? LCD_STR_FOLDER[0] : ' ');
     }
 
   #endif // SDSUPPORT
diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
index 645a4b6b3248c3e26b23eac66deec5edd7afcb18..e30633be882fc247f2b8a6af9d9955d395157b79 100644
--- a/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp
@@ -305,11 +305,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
         while (--pad >= 0) { lcd_put_wchar(' '); n--; }
       }
       n -= lcd_put_u8str_max_P(pstr, n);
-      if (NULL != valstr) {
-        n -= lcd_put_u8str_max(valstr, n);
-      }
-
-      while (n - MENU_FONT_WIDTH > 0) { n -= lcd_put_wchar(' '); }
+      if (valstr) n -= lcd_put_u8str_max(valstr, n);
+      while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
     }
   }
 
@@ -318,10 +315,9 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
     UNUSED(pre_char);
 
     if (mark_as_selected(row, sel)) {
-      uint8_t n = LCD_WIDTH - 2;
-      n *= MENU_FONT_WIDTH;
+      uint8_t n = (LCD_WIDTH - 2) * (MENU_FONT_WIDTH);
       n -= lcd_put_u8str_max_P(pstr, n);
-      while (n - MENU_FONT_WIDTH > 0) { n -= lcd_put_wchar(' '); }
+      while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
       lcd_moveto(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2);
       lcd_put_wchar(post_char);
       lcd_put_wchar(' ');
@@ -332,11 +328,10 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
   void _draw_menu_item_edit(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
     if (mark_as_selected(row, sel)) {
       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
-      uint8_t n = LCD_WIDTH - 2 - vallen;
-      n *= MENU_FONT_WIDTH;
+      uint8_t n = (LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH);
       n -= lcd_put_u8str_max_P(pstr, n);
       lcd_put_wchar(':');
-      while (n - MENU_FONT_WIDTH > 0) { n -= lcd_put_wchar(' '); }
+      while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
       lcd_moveto(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH) * vallen, row_y2);
       if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str((char*)data);
     }
@@ -399,37 +394,13 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
     void draw_sd_menu_item(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir) {
       UNUSED(pstr);
 
-      mark_as_selected(row, sel);
-
-      if (!PAGE_CONTAINS(row_y1, row_y2)) return;
-
-      constexpr uint8_t maxlen = LCD_WIDTH - 1;
-      const char *outstr = theCard.longest_filename();
-      if (theCard.longFilename[0]) {
-        #if ENABLED(SCROLL_LONG_FILENAMES)
-          static uint8_t filename_scroll_hash;
-          if (sel) {
-            uint8_t name_hash = row;
-            for (uint8_t l = FILENAME_LENGTH; l--;)
-              name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ theCard.filename[l];  // rotate, xor
-            if (filename_scroll_hash != name_hash) {                            // If the hash changed...
-              filename_scroll_hash = name_hash;                                 // Save the new hash
-              ui.filename_scroll_max = MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
-              ui.filename_scroll_pos = 0;                                       // Reset scroll to the start
-              ui.lcd_status_update_delay = 8;                                   // Don't scroll right away
-            }
-            outstr += ui.filename_scroll_pos;
-          }
-        #else
-          theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
-        #endif
+      if (mark_as_selected(row, sel)) {
+        if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
+        constexpr uint8_t maxlen = LCD_WIDTH - 1;
+        const uint8_t pixw = maxlen * (MENU_FONT_WIDTH);
+        uint8_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
+        while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
       }
-
-      if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
-
-      uint8_t n = lcd_put_u8str_max(outstr, maxlen * (MENU_FONT_WIDTH));
-      n = maxlen * (MENU_FONT_WIDTH) - n;
-      while (n - MENU_FONT_WIDTH > 0) { n -= lcd_put_wchar(' '); }
     }
 
   #endif // SDSUPPORT
diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp
index 5150264bc54c52c6031fa92219eca502591dd5cb..c1007810879a60ed84442fe6f9c0241e28cebb81 100644
--- a/Marlin/src/lcd/ultralcd.cpp
+++ b/Marlin/src/lcd/ultralcd.cpp
@@ -112,9 +112,37 @@ millis_t next_button_update_ms;
 
 #if HAS_LCD_MENU
   #include "menu/menu.h"
+  #include "../sd/cardreader.h"
+
+  #if ENABLED(SDSUPPORT)
+
+    #if ENABLED(SCROLL_LONG_FILENAMES)
+      uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
+    #endif
+
+    const char * const MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) {
+      const char *outstr = theCard.longest_filename();
+      if (theCard.longFilename[0]) {
+        #if ENABLED(SCROLL_LONG_FILENAMES)
+          if (doScroll) {
+            for (uint8_t l = FILENAME_LENGTH; l--;)
+              hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l];      // rotate, xor
+            static uint8_t filename_scroll_hash;
+            if (filename_scroll_hash != hash) {                              // If the hash changed...
+              filename_scroll_hash = hash;                                   // Save the new hash
+              filename_scroll_max = MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
+              filename_scroll_pos = 0;                                       // Reset scroll to the start
+              lcd_status_update_delay = 8;                                   // Don't scroll right away
+            }
+            outstr += filename_scroll_pos;
+          }
+        #else
+          theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
+        #endif
+      }
+      return outstr;
+    }
 
-  #if ENABLED(SDSUPPORT) && ENABLED(SCROLL_LONG_FILENAMES)
-    uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
   #endif
 
   screenFunc_t MarlinUI::currentScreen; // Initialized in CTOR
diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h
index dcafb30eea176ea296226630c0a5cf99dcea9283..af15a158e41094db01f6430099f7557bb5340cc7 100644
--- a/Marlin/src/lcd/ultralcd.h
+++ b/Marlin/src/lcd/ultralcd.h
@@ -23,6 +23,12 @@
 
 #include "../inc/MarlinConfig.h"
 
+#if HAS_BUZZER
+  #include "../libs/buzzer.h"
+#endif
+
+#define HAS_ENCODER_ACTION (HAS_LCD_MENU || ENABLED(ULTIPANEL_FEEDMULTIPLY))
+
 #if HAS_SPI_LCD
 
   #include "../Marlin.h"
@@ -32,16 +38,6 @@
     #include "../module/motion.h" // for active_extruder
   #endif
 
-#endif
-
-#if HAS_BUZZER
-  #include "../libs/buzzer.h"
-#endif
-
-#define HAS_ENCODER_ACTION (HAS_LCD_MENU || ENABLED(ULTIPANEL_FEEDMULTIPLY))
-
-#if HAS_SPI_LCD
-
   enum LCDViewAction : uint8_t {
     LCDVIEW_NONE,
     LCDVIEW_REDRAW_NOW,
@@ -66,6 +62,10 @@
 
   #if HAS_LCD_MENU
 
+    #if ENABLED(SDSUPPORT)
+      #include "../sd/cardreader.h"
+    #endif
+
     typedef void (*screenFunc_t)();
     typedef void (*menuAction_t)();
 
@@ -213,9 +213,6 @@
   };
 #endif
 
-#define LCD_MESSAGEPGM(x)      ui.setstatusPGM(PSTR(x))
-#define LCD_ALERTMESSAGEPGM(x) ui.setalertstatusPGM(PSTR(x))
-
 ////////////////////////////////////////////
 //////////// MarlinUI Singleton ////////////
 ////////////////////////////////////////////
@@ -379,8 +376,11 @@ public:
       static void enable_encoder_multiplier(const bool onoff);
     #endif
 
-    #if ENABLED(SCROLL_LONG_FILENAMES)
-      static uint8_t filename_scroll_pos, filename_scroll_max;
+    #if ENABLED(SDSUPPORT)
+      #if ENABLED(SCROLL_LONG_FILENAMES)
+        static uint8_t filename_scroll_pos, filename_scroll_max;
+      #endif
+      static const char * const scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll);
     #endif
 
     #if IS_KINEMATIC
@@ -524,3 +524,6 @@ private:
 };
 
 extern MarlinUI ui;
+
+#define LCD_MESSAGEPGM(x)      ui.setstatusPGM(PSTR(x))
+#define LCD_ALERTMESSAGEPGM(x) ui.setalertstatusPGM(PSTR(x))