From 445d8215e456d68239062f1a61a60c426a59f868 Mon Sep 17 00:00:00 2001
From: Kai <Kai@kaifehlis.de>
Date: Tue, 30 Aug 2016 08:18:31 +0200
Subject: [PATCH 1/2] Option to show SD percent on Graphical LCD

---
 Marlin/ultralcd_impl_DOGM.h | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h
index 8defa948011..b8dc4c78933 100644
--- a/Marlin/ultralcd_impl_DOGM.h
+++ b/Marlin/ultralcd_impl_DOGM.h
@@ -349,6 +349,8 @@ FORCE_INLINE void _draw_axis_label(AxisEnum axis, const char *pstr, bool blink)
   }
 }
 
+//#define DOGM_SD_PERCENT
+
 static void lcd_implementation_status_screen() {
   u8g.setColorIndex(1); // black on white
 
@@ -380,6 +382,13 @@ static void lcd_implementation_status_screen() {
     if (IS_SD_PRINTING) {
       // Progress bar solid part
       u8g.drawBox(55, 50, (unsigned int)(71 * card.percentDone() * 0.01), 2 - (TALL_FONT_CORRECTION));
+    
+      #if ENABLED(DOGM_SD_PERCENT)
+        // Percent complete
+        u8g.setPrintPos(55, 48);
+        u8g.print(itostr3(card.percentDone()));
+        u8g.print('%');
+      #endif
     }
 
     char buffer[10];
@@ -387,7 +396,13 @@ static void lcd_implementation_status_screen() {
     bool has_days = (elapsed.value > 60*60*24L);
     elapsed.toDigital(buffer, has_days);
 
-    u8g.setPrintPos(has_days ? 71 : 80, 48);
+    #if DISABLED(DOGM_SD_PERCENT)
+      #define SD_DURATION_X 71
+    #else
+      #define SD_DURATION_X 89
+    #endif
+
+    u8g.setPrintPos(SD_DURATION_X + (has_days ? 0 : 9), 48);
     lcd_print(buffer);
 
   #endif

From f20b2b21eb0434f3812952f6979ed6fac15e0a9f Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 2 Sep 2016 04:09:34 -0500
Subject: [PATCH 2/2] Optimize LCD string/char printing

---
 Marlin/ultralcd_impl_DOGM.h    | 65 ++++++++++++++++++----------------
 Marlin/ultralcd_impl_HD44780.h | 33 ++++++++---------
 2 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h
index b8dc4c78933..aeed61fc15d 100644
--- a/Marlin/ultralcd_impl_DOGM.h
+++ b/Marlin/ultralcd_impl_DOGM.h
@@ -189,29 +189,32 @@ static void lcd_setFont(char font_nr) {
   }
 }
 
-char lcd_print(char c) {
+void lcd_print(char c) {
+  if ((c > 0) && (c <= LCD_STR_SPECIAL_MAX)) {
+    u8g.setFont(FONT_SPECIAL_NAME);
+    u8g.print(c);
+    lcd_setFont(currentfont);
+  }
+  else charset_mapper(c);
+}
+
+char lcd_print_and_count(char c) {
   if ((c > 0) && (c <= LCD_STR_SPECIAL_MAX)) {
     u8g.setFont(FONT_SPECIAL_NAME);
     u8g.print(c);
     lcd_setFont(currentfont);
     return 1;
-  } else {
-    return charset_mapper(c);
   }
+  else return charset_mapper(c);
 }
 
-char lcd_print(const char* str) {
-  int i = 0;
-  char c, n = 0;
-  while ((c = str[i++])) n += lcd_print(c);
-  return n;
+void lcd_print(const char* str) {
+  for (uint8_t i = 0; char c = str[i]; ++i) lcd_print(c);
 }
 
-// Needed for Arduino < 1.0.0
-char lcd_printPGM(const char* str) {
-  char c, n = 0;
-  while ((c = pgm_read_byte(str++))) n += lcd_print(c);
-  return n;
+/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
+void lcd_printPGM(const char* str) {
+  for (; char c = pgm_read_byte(str); ++str) lcd_print(c);
 }
 
 // Initialize or re-initializw the LCD
@@ -337,11 +340,11 @@ FORCE_INLINE void _draw_axis_label(AxisEnum axis, const char *pstr, bool blink)
     lcd_printPGM(pstr);
   else {
     if (!axis_homed[axis])
-      lcd_printPGM(PSTR("?"));
+      u8g.print('?');
     else {
       #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
         if (!axis_known_position[axis])
-          lcd_printPGM(PSTR(" "));
+          u8g.print(' ');
         else
       #endif
       lcd_printPGM(pstr);
@@ -421,7 +424,7 @@ static void lcd_implementation_status_screen() {
     int per = ((fanSpeeds[0] + 1) * 100) / 256;
     if (per) {
       lcd_print(itostr3(per));
-      lcd_print('%');
+      u8g.print('%');
     }
   #endif
 
@@ -463,7 +466,7 @@ static void lcd_implementation_status_screen() {
   lcd_setFont(FONT_STATUSMENU);
   u8g.setPrintPos(12, 49);
   lcd_print(itostr3(feedrate_percentage));
-  lcd_print('%');
+  u8g.print('%');
 
   // Status line
   #if ENABLED(USE_SMALL_INFOFONT)
@@ -482,7 +485,7 @@ static void lcd_implementation_status_screen() {
       lcd_print(ftostr12ns(filament_width_meas));
       lcd_printPGM(PSTR(" factor:"));
       lcd_print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
-      lcd_print('%');
+      u8g.print('%');
     }
   #endif
 }
@@ -514,17 +517,17 @@ static void lcd_implementation_status_screen() {
 
       if (center && !valstr) {
         int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2;
-        while (--pad >= 0) { lcd_print(' '); n--; }
+        while (--pad >= 0) { u8g.print(' '); n--; }
       }
       while (n > 0 && (c = pgm_read_byte(pstr))) {
-        n -= lcd_print(c);
+        n -= lcd_print_and_count(c);
         pstr++;
       }
       if (valstr) while (n > 0 && (c = *valstr)) {
-        n -= lcd_print(c);
+        n -= lcd_print_and_count(c);
         valstr++;
       }
-      while (n-- > 0) lcd_print(' ');
+      while (n-- > 0) u8g.print(' ');
     }
 
   #endif // LCD_INFO_MENU || FILAMENT_CHANGE_FEATURE
@@ -539,13 +542,13 @@ static void lcd_implementation_status_screen() {
     lcd_implementation_mark_as_selected(row, isSelected);
 
     while (c = pgm_read_byte(pstr)) {
-      n -= lcd_print(c);
+      n -= lcd_print_and_count(c);
       pstr++;
     }
-    while (n--) lcd_print(' ');
+    while (n--) u8g.print(' ');
     u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), (row + 1) * (DOG_CHAR_HEIGHT));
     lcd_print(post_char);
-    lcd_print(' ');
+    u8g.print(' ');
   }
 
   // Macros for specific types of menu items
@@ -563,11 +566,11 @@ static void lcd_implementation_status_screen() {
     lcd_implementation_mark_as_selected(row, isSelected);
 
     while (c = pgm_read_byte(pstr)) {
-      n -= lcd_print(c);
+      n -= lcd_print_and_count(c);
       pstr++;
     }
-    lcd_print(':');
-    while (n--) lcd_print(' ');
+    u8g.print(':');
+    while (n--) u8g.print(' ');
     u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH) * vallen, (row + 1) * (DOG_CHAR_HEIGHT));
     if (pgm)  lcd_printPGM(data);  else  lcd_print((char*)data);
   }
@@ -621,7 +624,7 @@ static void lcd_implementation_status_screen() {
     u8g.setPrintPos(0, rowHeight + kHalfChar);
     lcd_printPGM(pstr);
     if (value != NULL) {
-      lcd_print(':');
+      u8g.print(':');
       u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar);
       lcd_print(value);
     }
@@ -643,10 +646,10 @@ static void lcd_implementation_status_screen() {
 
       if (isDir) lcd_print(LCD_STR_FOLDER[0]);
       while ((c = *filename)) {
-        n -= lcd_print(c);
+        n -= lcd_print_and_count(c);
         filename++;
       }
-      while (n--) lcd_print(' ');
+      while (n--) u8g.print(' ');
     }
 
     #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false)
diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h
index 44d0bb977fb..3babc65d948 100644
--- a/Marlin/ultralcd_impl_HD44780.h
+++ b/Marlin/ultralcd_impl_HD44780.h
@@ -375,20 +375,15 @@ static void lcd_implementation_init(
 static void lcd_implementation_clear() { lcd.clear(); }
 
 /* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
-char lcd_printPGM(const char* str) {
-  char c, n = 0;
-  while ((c = pgm_read_byte(str++))) n += charset_mapper(c);
-  return n;
+void lcd_printPGM(const char *str) {
+  for (; char c = pgm_read_byte(str); ++str) charset_mapper(c);
 }
 
-char lcd_print(const char* str) {
-  char c, n = 0;
-  unsigned char i = 0;
-  while ((c = str[i++])) n += charset_mapper(c);
-  return n;
+void lcd_print(const char* str) {
+  for (uint8_t i = 0; char c = str[i]; ++i) charset_mapper(c);
 }
 
-unsigned lcd_print(char c) { return charset_mapper(c); }
+void lcd_print(char c) { charset_mapper(c); }
 
 #if ENABLED(SHOW_BOOTSCREEN)
 
@@ -556,11 +551,11 @@ FORCE_INLINE void _draw_axis_label(AxisEnum axis, const char *pstr, bool blink)
     lcd_printPGM(pstr);
   else {
     if (!axis_homed[axis])
-      lcd_printPGM(PSTR("?"));
+      lcd.print('?');
     else {
       #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
         if (!axis_known_position[axis])
-          lcd_printPGM(PSTR(" "));
+          lcd.print(' ');
         else
       #endif
       lcd_printPGM(pstr);
@@ -694,7 +689,7 @@ static void lcd_implementation_status_screen() {
         _draw_axis_label(X_AXIS, PSTR(MSG_X), blink);
         lcd.print(ftostr4sign(current_position[X_AXIS]));
 
-        lcd_printPGM(PSTR(" "));
+        lcd.print(' ');
 
         _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink);
         lcd.print(ftostr4sign(current_position[Y_AXIS]));
@@ -803,11 +798,11 @@ static void lcd_implementation_status_screen() {
         while (--pad >= 0) { lcd.print(' '); n--; }
       }
       while (n > 0 && (c = pgm_read_byte(pstr))) {
-        n -= lcd_print(c);
+        n -= charset_mapper(c);
         pstr++;
       }
       if (valstr) while (n > 0 && (c = *valstr)) {
-        n -= lcd_print(c);
+        n -= charset_mapper(c);
         valstr++;
       }
       while (n-- > 0) lcd.print(' ');
@@ -821,7 +816,7 @@ static void lcd_implementation_status_screen() {
     lcd.setCursor(0, row);
     lcd.print(sel ? pre_char : ' ');
     while ((c = pgm_read_byte(pstr)) && n > 0) {
-      n -= lcd_print(c);
+      n -= charset_mapper(c);
       pstr++;
     }
     while (n--) lcd.print(' ');
@@ -834,7 +829,7 @@ static void lcd_implementation_status_screen() {
     lcd.setCursor(0, row);
     lcd.print(sel ? pre_char : ' ');
     while ((c = pgm_read_byte(pstr)) && n > 0) {
-      n -= lcd_print(c);
+      n -= charset_mapper(c);
       pstr++;
     }
     lcd.print(':');
@@ -847,7 +842,7 @@ static void lcd_implementation_status_screen() {
     lcd.setCursor(0, row);
     lcd.print(sel ? pre_char : ' ');
     while ((c = pgm_read_byte(pstr)) && n > 0) {
-      n -= lcd_print(c);
+      n -= charset_mapper(c);
       pstr++;
     }
     lcd.print(':');
@@ -899,7 +894,7 @@ static void lcd_implementation_status_screen() {
         longFilename[n] = '\0';
       }
       while ((c = *filename) && n > 0) {
-        n -= lcd_print(c);
+        n -= charset_mapper(c);
         filename++;
       }
       while (n--) lcd.print(' ');