ソースを参照

[2.0.x] Buffer overflow and scroll fix, UTF8 cleanup (#10844)

Eduardo José Tagle 6年前
コミット
6f330f397e

+ 10
- 18
Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp ファイルの表示

@@ -162,22 +162,15 @@ void spiBegin (void) {
162 162
     // away. When clock is not known, use a loop instead, which generates
163 163
     // shorter code.
164 164
     if (__builtin_constant_p(spiClock)) {
165
-      if (spiClock >= F_CPU / 2) {
166
-        clockDiv = 0;
167
-      } else if (spiClock >= F_CPU / 4) {
168
-        clockDiv = 1;
169
-      } else if (spiClock >= F_CPU / 8) {
170
-        clockDiv = 2;
171
-      } else if (spiClock >= F_CPU / 16) {
172
-        clockDiv = 3;
173
-      } else if (spiClock >= F_CPU / 32) {
174
-        clockDiv = 4;
175
-      } else if (spiClock >= F_CPU / 64) {
176
-        clockDiv = 5;
177
-      } else {
178
-        clockDiv = 6;
179
-      }
180
-    } else {
165
+      if (spiClock >= F_CPU / 2)       clockDiv = 0;
166
+      else if (spiClock >= F_CPU / 4)  clockDiv = 1;
167
+      else if (spiClock >= F_CPU / 8)  clockDiv = 2;
168
+      else if (spiClock >= F_CPU / 16) clockDiv = 3;
169
+      else if (spiClock >= F_CPU / 32) clockDiv = 4;
170
+      else if (spiClock >= F_CPU / 64) clockDiv = 5;
171
+      else                             clockDiv = 6;
172
+    }
173
+    else {
181 174
       uint32_t clockSetting = F_CPU / 2;
182 175
       clockDiv = 0;
183 176
       while (clockDiv < 6 && spiClock < clockSetting) {
@@ -187,8 +180,7 @@ void spiBegin (void) {
187 180
     }
188 181
 
189 182
     // Compensate for the duplicate fosc/64
190
-    if (clockDiv == 6)
191
-      clockDiv = 7;
183
+    if (clockDiv == 6) clockDiv = 7;
192 184
 
193 185
     // Invert the SPI2X bit
194 186
     clockDiv ^= 0x1;

+ 0
- 1
Marlin/src/feature/bedlevel/ubl/ubl.h ファイルの表示

@@ -56,7 +56,6 @@ extern uint8_t ubl_cnt;
56 56
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
57 57
 
58 58
 #if ENABLED(ULTRA_LCD)
59
-  extern char lcd_status_message[];
60 59
   void lcd_quick_feedback(const bool clear_buttons);
61 60
 #endif
62 61
 

+ 0
- 6
Marlin/src/gcode/bedlevel/G26.cpp ファイルの表示

@@ -135,10 +135,6 @@
135 135
 
136 136
 // External references
137 137
 
138
-#if ENABLED(ULTRA_LCD)
139
-  extern char lcd_status_message[];
140
-#endif
141
-
142 138
 // Private functions
143 139
 
144 140
 static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
@@ -508,8 +504,6 @@ inline bool prime_nozzle() {
508 504
 
509 505
       wait_for_release();
510 506
 
511
-      strcpy_P(lcd_status_message, PSTR("Done Priming")); // Hack to get the message up. May be obsolete.
512
-
513 507
       lcd_setstatusPGM(PSTR("Done Priming"), 99);
514 508
       lcd_quick_feedback(true);
515 509
       lcd_external_control = false;

+ 2
- 5
Marlin/src/gcode/calibrate/G33.cpp ファイルの表示

@@ -519,15 +519,12 @@ void GcodeSuite::G33() {
519 519
   }
520 520
 
521 521
   // Report settings
522
-
523
-  const char *checkingac = PSTR("Checking... AC");
522
+  const char* checkingac = PSTR("Checking... AC");
524 523
   serialprintPGM(checkingac);
525 524
   if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)");
526 525
   if (set_up) SERIAL_PROTOCOLPGM("  (SET-UP)");
527 526
   SERIAL_EOL();
528
-  char mess[11];
529
-  strcpy_P(mess, checkingac);
530
-  lcd_setstatus(mess);
527
+  lcd_setstatusPGM(checkingac);
531 528
 
532 529
   print_calibration_settings(_endstop_results, _angle_results);
533 530
 

+ 66
- 25
Marlin/src/lcd/dogm/status_screen_DOGM.h ファイルの表示

@@ -33,7 +33,7 @@ FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t x, const
33 33
   const char * const str = itostr3(temp);
34 34
   lcd_moveto(x - (str[0] != ' ' ? 0 : str[1] != ' ' ? 1 : 2) * DOG_CHAR_WIDTH / 2, y);
35 35
   lcd_put_u8str(str);
36
-  lcd_put_u8str_rom(PSTR(LCD_STR_DEGREE " "));
36
+  lcd_put_u8str_P(PSTR(LCD_STR_DEGREE " "));
37 37
 }
38 38
 
39 39
 #ifndef HEAT_INDICATOR_X
@@ -113,7 +113,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
113 113
     else {
114 114
       #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
115 115
         if (!axis_known_position[axis])
116
-          lcd_put_u8str_rom(axis == Z_AXIS ? PSTR("      ") : PSTR("    "));
116
+          lcd_put_u8str_P(axis == Z_AXIS ? PSTR("      ") : PSTR("    "));
117 117
         else
118 118
       #endif
119 119
           lcd_put_u8str(value);
@@ -124,36 +124,77 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
124 124
 inline void lcd_implementation_status_message(const bool blink) {
125 125
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
126 126
     static bool last_blink = false;
127
-    const uint8_t slen = utf8_strlen(lcd_status_message);
128
-    const char *stat = lcd_status_message + status_scroll_pos;
129
-    if (slen <= LCD_WIDTH)
130
-      lcd_put_u8str(stat);                                      // The string isn't scrolling
127
+
128
+    // Get the UTF8 character count of the string
129
+    uint8_t slen = utf8_strlen(lcd_status_message);
130
+
131
+    // If the string fits into the LCD, just print it and do not scroll it
132
+    if (slen <= LCD_WIDTH) {
133
+
134
+      // The string isn't scrolling and may not fill the screen
135
+      lcd_put_u8str(lcd_status_message);
136
+
137
+      // Fill the rest with spaces
138
+      while (slen < LCD_WIDTH) {
139
+        lcd_put_wchar(' ');
140
+        ++slen;
141
+      }
142
+    }
131 143
     else {
132
-      if (status_scroll_pos <= slen - LCD_WIDTH)
133
-        lcd_put_u8str(stat);                                    // The string fills the screen
144
+      // String is larger than the available space in screen.
145
+
146
+      // Get a pointer to the next valid UTF8 character
147
+      const char *stat = lcd_status_message + status_scroll_offset;
148
+
149
+      // Get the string remaining length
150
+      const uint8_t rlen = utf8_strlen(stat);
151
+
152
+      // If we have enough characters to display
153
+      if (rlen >= LCD_WIDTH) {
154
+        // The remaining string fills the screen - Print it
155
+        lcd_put_u8str_max(stat, LCD_PIXEL_WIDTH);
156
+      }
134 157
       else {
135
-        uint8_t chars = LCD_WIDTH;
136
-        if (status_scroll_pos < slen) {                         // First string still visible
137
-          lcd_put_u8str(stat);                                  // The string leaves space
138
-          chars -= slen - status_scroll_pos;                    // Amount of space left
139
-        }
140
-        lcd_put_wchar('.');                                         // Always at 1+ spaces left, draw a dot
141
-        if (--chars) {
142
-          if (status_scroll_pos < slen + 1)                     // Draw a second dot if there's space
143
-            --chars, lcd_put_wchar('.');
144
-          if (chars) lcd_put_u8str_max(lcd_status_message, chars);  // Print a second copy of the message
158
+        // The remaining string does not completely fill the screen
159
+        lcd_put_u8str_max(stat, LCD_PIXEL_WIDTH);         // The string leaves space
160
+        uint8_t chars = LCD_WIDTH - rlen;                 // Amount of space left in characters
161
+
162
+        lcd_put_wchar('.');                               // Always at 1+ spaces left, draw a dot
163
+        if (--chars) {                                    // Draw a second dot if there's space
164
+          lcd_put_wchar('.');
165
+          if (--chars) {
166
+            // Print a second copy of the message
167
+            lcd_put_u8str_max(lcd_status_message, LCD_PIXEL_WIDTH - ((rlen+2) * DOG_CHAR_WIDTH)); 
168
+          }
145 169
         }
146 170
       }
147 171
       if (last_blink != blink) {
148 172
         last_blink = blink;
149
-        // Skip any non-printing bytes
150
-        if (status_scroll_pos < slen) while (!PRINTABLE(lcd_status_message[status_scroll_pos])) status_scroll_pos++;
151
-        if (++status_scroll_pos >= slen + 2) status_scroll_pos = 0;
173
+
174
+        // Adjust by complete UTF8 characters
175
+        if (status_scroll_offset < slen) {
176
+          status_scroll_offset++;
177
+          while (!START_OF_UTF8_CHAR(lcd_status_message[status_scroll_offset]))
178
+            status_scroll_offset++;
179
+        }
180
+        else
181
+          status_scroll_offset = 0;
152 182
       }
153 183
     }
154 184
   #else
155 185
     UNUSED(blink);
156
-    lcd_put_u8str(lcd_status_message);
186
+
187
+    // Get the UTF8 character count of the string
188
+    uint8_t slen = utf8_strlen(lcd_status_message);
189
+
190
+    // Just print the string to the LCD
191
+    lcd_put_u8str_max(lcd_status_message, LCD_PIXEL_WIDTH);
192
+
193
+    // Fill the rest with spaces if there are missing spaces
194
+    while (slen < LCD_WIDTH) {
195
+      lcd_put_wchar(' ');
196
+      ++slen;
197
+    }
157 198
   #endif
158 199
 }
159 200
 
@@ -417,7 +458,7 @@ static void lcd_implementation_status_screen() {
417 458
       lcd_put_wchar('%');
418 459
       lcd_setFont(FONT_MENU);
419 460
       lcd_moveto(47, 50);
420
-      lcd_put_wchar(LCD_STR_FILAM_DIA[0]); // lcd_put_u8str_rom(PSTR(LCD_STR_FILAM_DIA));
461
+      lcd_put_wchar(LCD_STR_FILAM_DIA[0]); // lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
421 462
       lcd_moveto(93, 50);
422 463
       lcd_put_wchar(LCD_STR_FILAM_MUL[0]);
423 464
     #endif
@@ -437,10 +478,10 @@ static void lcd_implementation_status_screen() {
437 478
         lcd_implementation_status_message(blink);
438 479
       }
439 480
       else {
440
-        lcd_put_u8str_rom(PSTR(LCD_STR_FILAM_DIA));
481
+        lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
441 482
         lcd_put_wchar(':');
442 483
         lcd_put_u8str(wstring);
443
-        lcd_put_u8str_rom(PSTR("  " LCD_STR_FILAM_MUL));
484
+        lcd_put_u8str_P(PSTR("  " LCD_STR_FILAM_MUL));
444 485
         lcd_put_wchar(':');
445 486
         lcd_put_u8str(mstring);
446 487
         lcd_put_wchar('%');

+ 55
- 20
Marlin/src/lcd/dogm/status_screen_lite_ST7920.h ファイルの表示

@@ -615,36 +615,71 @@ void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint8_t percentag
615 615
 void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
616 616
   set_ddram_address(DDRAM_LINE_4);
617 617
   begin_data();
618
+  const uint8_t lcd_len = 16;
618 619
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
619
-    const uint8_t lcd_len = 16;
620
-    const uint8_t padding = 2;
621
-    uint8_t str_len = strlen(str);
622 620
 
623
-    // Trim whitespace at the end of the str, as for some reason
624
-    // messages like "Card Inserted" are padded with many spaces
625
-    while (str_len && str[str_len - 1] == ' ') str_len--;
621
+    uint8_t slen = utf8_strlen(str);
626 622
 
627
-    if (str_len <= lcd_len) {
628
-      // It all fits on the LCD without scrolling
623
+    // If the string fits into the LCD, just print it and do not scroll it
624
+    if (slen <= lcd_len) {
625
+
626
+      // The string isn't scrolling and may not fill the screen
629 627
       write_str(str);
628
+
629
+      // Fill the rest with spaces
630
+      while (slen < lcd_len) {
631
+        write_byte(' ');
632
+        ++slen;
633
+      }
630 634
     }
631 635
     else {
632
-      // Print the message repeatedly until covering the LCD
633
-      uint8_t c = status_scroll_pos;
634
-      for (uint8_t n = 0; n < lcd_len; n++) {
635
-        write_byte(c < str_len ? str[c] : ' ');
636
-        c++;
637
-        c %= str_len + padding; // Wrap around
636
+      // String is larger than the available space in screen.
637
+
638
+      // Get a pointer to the next valid UTF8 character
639
+      const char *stat = str + status_scroll_offset;
640
+
641
+      // Get the string remaining length
642
+      const uint8_t rlen = utf8_strlen(stat);
643
+
644
+      // If we have enough characters to display
645
+      if (rlen >= lcd_len) {
646
+        // The remaining string fills the screen - Print it
647
+        write_str(stat, lcd_len);
648
+      }
649
+      else {
650
+        // The remaining string does not completely fill the screen
651
+        write_str(stat);                        // The string leaves space
652
+        uint8_t chars = lcd_len - rlen;         // Amount of space left in characters
653
+
654
+        write_byte('.');                        // Always at 1+ spaces left, draw a dot
655
+        if (--chars) {                          // Draw a second dot if there's space
656
+          write_byte('.');
657
+          if (--chars)
658
+            write_str(str, chars);              // Print a second copy of the message
659
+        }
638 660
       }
639 661
 
640
-      // Scroll the message
641
-      if (status_scroll_pos == str_len + padding)
642
-        status_scroll_pos = 0;
662
+      // Adjust by complete UTF8 characters
663
+      if (status_scroll_offset < slen) {
664
+        status_scroll_offset++;
665
+        while (!START_OF_UTF8_CHAR(str[status_scroll_offset]))
666
+          status_scroll_offset++;
667
+      }
643 668
       else
644
-        status_scroll_pos++;
669
+        status_scroll_offset = 0;
645 670
     }
646 671
   #else
647
-    write_str(str, 16);
672
+    // Get the UTF8 character count of the string
673
+    uint8_t slen = utf8_strlen(str);
674
+
675
+    // Just print the string to the LCD
676
+    write_str(str, lcd_len);
677
+
678
+    // Fill the rest with spaces if there are missing spaces
679
+    while (slen < lcd_len) {
680
+      write_byte(' ');
681
+      ++slen;
682
+    }
648 683
   #endif
649 684
 }
650 685
 
@@ -792,7 +827,7 @@ void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
792 827
    */
793 828
   if (forceUpdate || status_changed()) {
794 829
     #if ENABLED(STATUS_MESSAGE_SCROLLING)
795
-      status_scroll_pos = 0;
830
+      status_scroll_offset = 0;
796 831
     #endif
797 832
     #if STATUS_EXPIRE_SECONDS
798 833
       countdown = lcd_status_message[0] ? STATUS_EXPIRE_SECONDS : 0;

+ 20
- 164
Marlin/src/lcd/fontutils.cpp ファイルの表示

@@ -16,56 +16,14 @@
16 16
 
17 17
 #include "fontutils.h"
18 18
 
19
-uint8_t read_byte_ram(uint8_t * str) { return *str; }
20
-uint8_t read_byte_rom(uint8_t * str) { return pgm_read_byte(str); }
21
-
22
-#if DEBUG
23
-  #ifdef ARDUINO
24
-    #include <Arduino.h>
25
-    #include <stdarg.h>
26
-
27
-    void serial_printf_P(const char *format, ...) {
28
-      static char buff[128];
29
-      va_list args;
30
-      va_start(args,format);
31
-      vsnprintf_P(buff,sizeof(buff),format,args);
32
-      va_end(args);
33
-      buff[sizeof(buff)/sizeof(buff[0])-1]='\0';
34
-
35
-      //Serial.print(buff);
36
-      SERIAL_ECHO(buff); SERIAL_EOL;
37
-    }
38
-  #endif
39
-#endif
40
-
41
-
42
-#ifdef __WIN32__                // or whatever
43
-  #define PRIiSZ "ld"
44
-  #define PRIuSZ "Iu"
45
-#else
46
-  #define PRIiSZ "zd"
47
-  #define PRIuSZ "zu"
48
-#endif
49
-#define PRIiOFF "lld"
50
-#define PRIuOFF "llu"
51
-
19
+uint8_t read_byte_ram(uint8_t * str) {
20
+  return *str;
21
+}
52 22
 
53
-#define DBGMSG(a,b, ...) TRACE( #__VA_ARGS__ )
23
+uint8_t read_byte_rom(uint8_t * str) {
24
+  return pgm_read_byte(str);
25
+}
54 26
 
55
-//typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin); /*"data_list[idx] - *data_pin"*/
56
-/**
57
- * @brief 折半方式查找记录
58
- *
59
- * @param userdata : 用户数据指针
60
- * @param num_data : 数据个数
61
- * @param cb_comp : 比较两个数据的回调函数
62
- * @param data_pinpoint : 所要查找的 匹配数据指针
63
- * @param ret_idx : 查找到的位置;如果没有找到,则返回如添加该记录时其所在的位置。
64
- *
65
- * @return 找到则返回0,否则返回<0
66
- *
67
- * 折半方式查找记录, psl->marr 中指向的数据已经以先小后大方式排好序
68
- */
69 27
 /**
70 28
  * @brief Using binary search to find the position by data_pin
71 29
  *
@@ -82,21 +40,11 @@ uint8_t read_byte_rom(uint8_t * str) { return pgm_read_byte(str); }
82 40
 int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx) {
83 41
   int retcomp;
84 42
 
85
-  FU_ASSERT(NULL != ret_idx);
86
-  /* 查找合适的位置 */
87 43
   if (num_data < 1) {
88 44
     *ret_idx = 0;
89
-    DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_ERROR, "num_data(%" PRIuSZ ") < 1", num_data);
90 45
     return -1;
91 46
   }
92 47
 
93
-  /* 折半查找 */
94
-  /* 为了不出现负数,以免缩小索引的所表示的数据范围
95
-   * (负数表明减少一位二进制位的使用),
96
-   * 内部 ileft 和 iright使用从1开始的下标,
97
-   *   即1表示C语言中的0, 2表示语言中的1,以此类推。
98
-   * 对外还是使用以 0 为开始的下标
99
-   */
100 48
   size_t i = 0, ileft = 1, iright = num_data;
101 49
   bool flg_found = false;
102 50
   for (; ileft <= iright;) {
@@ -122,28 +70,15 @@ int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp,
122 70
     *ret_idx = i;
123 71
   else if (ileft >= i + 2)
124 72
     *ret_idx = i + 1;
125
-  //DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_DEBUG, "not found! num_data=%" PRIuSZ "; ileft=%" PRIuSZ ", iright=%" PRIuSZ ", i=%" PRIuSZ "", num_data, ileft, iright, i);
126 73
   return -1;
127 74
 }
128 75
 
129
-/**
130
- * @brief 转换 UTF-8 编码的一个字符为本地的 Unicode 字符(wchar_t)
131
- *
132
- * @param pstart : 存储 UTF-8 字符的指针
133
- * @param cb_read_byte : 读取字符的函数;用于8位MCU ROM
134
- * @param pval : 需要返回的 Unicode 字符存放地址指针
135
- *
136
- * @return 成功返回下个 UTF-8 字符的位置
137
- *
138
- * 转换 UTF-8 编码的一个字符为本地的 Unicode 字符(wchar_t)
139
- */
76
+/* This function gets the character at the pstart position, interpreting UTF8 multybyte sequences
77
+   and returns the pointer to the next character */
140 78
 uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
141 79
   uint32_t val = 0;
142 80
   uint8_t *p = pstart;
143 81
 
144
-  FU_ASSERT(NULL != pstart);
145
-  FU_ASSERT(NULL != cb_read_byte);
146
-
147 82
   uint8_t valcur = cb_read_byte(p);
148 83
   if (0 == (0x80 & valcur)) {
149 84
     val = valcur;
@@ -215,113 +150,34 @@ uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t
215 150
     val |= (valcur & 0x3F);
216 151
     p++;
217 152
   }
218
-  else if (0x80 == (0xC0 & valcur)) {
219
-    /* error? */
220
-    TRACE("ERR 1");
153
+  else if (0x80 == (0xC0 & valcur))
221 154
     for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
222
-  }
223
-  else {
224
-    /* error */
225
-    TRACE("ERR 2");
155
+  else
226 156
     for (; ((0xFE & valcur) > 0xFC); ) { p++; valcur = cb_read_byte(p); }
227
-  }
228
-  /*
229
-    if (val == 0) {
230
-      p = NULL;
231
-  */
232
-  /*
233
-    }
234
-    else if (pstart + maxlen < p) {
235
-      p = pstart;
236
-      if (pval) *pval = 0;
237
-    }
238
-  */
239 157
 
240 158
   if (pval) *pval = val;
241 159
 
242 160
   return p;
243 161
 }
244 162
 
245
-// uint8_t * get_utf8_value_cb (uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
246
-int utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
247
-  wchar_t ch;
248
-  uint8_t *pnext;
249
-  int cnt = 0;
163
+static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
250 164
 
251
-  for (pnext = (uint8_t *)pstart; ; ) {
165
+  uint8_t cnt = 0;
166
+  uint8_t *pnext = (uint8_t *)pstart;
167
+  for (;;) {
168
+    wchar_t ch;
252 169
     pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
253
-    if (pnext == NULL || ch == 0) break;
170
+    if (!ch) break;
254 171
     cnt++;
255
-    TRACE("cnt=%d, ch=0x%X", cnt, (int)ch);
256 172
   }
257 173
   return cnt;
258 174
 }
259 175
 
260
-int
261
-my_strlen_P(const char *pstart)
262
-{
263
-  const char *p;
264
-  FU_ASSERT(NULL != pstart);
265
-  p = pstart;
266
-  while (p && pgm_read_byte(p) != '\0') p ++;
267
-  return (p - pstart);
176
+uint8_t utf8_strlen(const char *pstart) {
177
+  return utf8_strlen_cb(pstart, read_byte_ram);
268 178
 }
269 179
 
270
-uint8_t utf8_strlen(const char *pstart)   { return utf8_strlen_cb(pstart, read_byte_ram); }
271
-uint8_t utf8_strlen_P(const char *pstart) { return utf8_strlen_cb(pstart, read_byte_rom); }
272
-
273
-char* utf8_strncpy_cb( char * destination, const char *source, size_t num, int len_src, read_byte_cb_t cb_read_byte) {
274
-  uint8_t *p = (uint8_t *)source;
275
-  uint8_t *d = (uint8_t *)destination;
276
-
277
-  FU_ASSERT(NULL != destination);
278
-  FU_ASSERT(NULL != source);
279
-  FU_ASSERT(NULL != cb_read_byte);
280
-
281
-  uint8_t *pend = p + len_src;
282
-
283
-  while (p < pend) {
284
-    uint8_t valcur = cb_read_byte(p);
285
-    size_t len = 0;
286
-    if (0 == (0x80 & valcur))
287
-      len = 1;
288
-    else if (0xC0 == (0xE0 & valcur))
289
-      len = 2;
290
-    else if (0xE0 == (0xF0 & valcur))
291
-      len = 3;
292
-    else if (0xF0 == (0xF8 & valcur))
293
-      len = 4;
294
-    else if (0xF8 == (0xFC & valcur))
295
-      len = 5;
296
-    else if (0xFC == (0xFE & valcur))
297
-      len = 6;
298
-    else if (0x80 == (0xC0 & valcur)) {
299
-      /* error? */
300
-      for (; 0x80 == (0xC0 & valcur) && (p < pend); ) { p++; valcur = cb_read_byte(p); }
301
-    }
302
-    else {
303
-      /* error */
304
-      for (; ((0xFE & valcur) > 0xFC) && (p < pend); ) { p++; valcur = cb_read_byte(p); }
305
-    }
306
-    if (len < num) {
307
-      for (size_t i = 0; i < len; i++) {
308
-        valcur = cb_read_byte(p);
309
-        *d = valcur;
310
-        d++;
311
-        p++;
312
-      }
313
-    }
314
-    else
315
-      break;
316
-  }
317
-  *d = 0;
318
-  return destination;
319
-}
320
-
321
-char* utf8_strncpy(char * destination, const char * source, size_t num) {
322
-  return utf8_strncpy_cb(destination, source, num, strlen(source), read_byte_ram);
180
+uint8_t utf8_strlen_P(const char *pstart) {
181
+  return utf8_strlen_cb(pstart, read_byte_rom);
323 182
 }
324 183
 
325
-char* utf8_strncpy_P(char * destination, const char * source, size_t num) {
326
-  return utf8_strncpy_cb(destination, source, num, my_strlen_P(source), read_byte_rom);
327
-}

+ 16
- 127
Marlin/src/lcd/fontutils.h ファイルの表示

@@ -9,151 +9,40 @@
9 9
 #ifndef _FONT_UTILS_H
10 10
 #define _FONT_UTILS_H
11 11
 
12
-#define DEBUG 0
13
-
14
-#ifdef ARDUINO
15
-  #include <Arduino.h>
16
-#else // ARDUINO
17
-  #include <stdint.h>
18
-  #include <stdio.h>
19
-  #include <stdlib.h>
20
-#endif // ARDUINO
21
-
22
-#ifndef pgm_read_word_near // __AVR__
23
-  #include <stdint.h>
24
-  #include <string.h>
25
-  #include <assert.h>
26
-  //#define pgm_read_word_near(a) *((uint16_t *)(a))
27
-  #define pgm_read_word_near(a) (*(a))
28
-  #define pgm_read_byte_near(a) *((uint8_t *)(a))
29
-  #define pgm_read_byte pgm_read_byte_near
30
-#elif defined(__AVR__)
31
-  #include <avr/pgmspace.h>
32
-#endif
33
-
34
-#ifndef PROGMEM
35
-  #define PROGMEM
36
-  #define strlen_P strlen
37
-  #define memcpy_P memcpy
38
-  #define vsnprintf_P vsnprintf
39
-#endif // PROGMEM
40
-
41
-#ifdef __cplusplus
42
-extern "C" {
43
-#endif
12
+#include <Arduino.h>
13
+#include "../core/macros.h"
14
+#include <stddef.h> // wchar_t
15
+#include <stdint.h> // uint32_t
44 16
 
45 17
 // read a byte from ROM or RAM
46
-typedef uint8_t (* read_byte_cb_t)(uint8_t * str);
18
+typedef uint8_t (*read_byte_cb_t)(uint8_t * str);
47 19
 
48
-//inline uint8_t read_byte_ram(uint8_t * str) { return *str; }
49
-//inline uint8_t read_byte_rom(uint8_t * str) { return pgm_read_byte(str); }
50 20
 uint8_t read_byte_ram(uint8_t * str);
51 21
 uint8_t read_byte_rom(uint8_t * str);
52 22
 
53
-#ifdef __cplusplus
54
-}
55
-#endif
56
-
57
-#include <stddef.h> // wchar_t
58
-#include <stdint.h> // uint32_t
59
-
60
-#ifdef ARDUINO
61
-
62
-  // there's overflow of the wchar_t due to the 2-byte size in Arduino
63
-  // sizeof(wchar_t)=2; sizeof(size_t)=2; sizeof(uint32_t)=4;
64
-  // sizeof(int)=2; sizeof(long)=4; sizeof(unsigned)=2;
65
-  //#undef wchar_t
66
-  #define wchar_t uint32_t
67
-  //typedef uint32_t wchar_t;
68
-
69
-#else
70
-
71
-  #include <sys/types.h> // ssize_t
72
-  #include <assert.h>
73
-  // x86_64
74
-  // sizeof(wchar_t)=4; sizeof(size_t)=8; sizeof(uint32_t)=4;
75
-  // sizeof(int)=4; sizeof(long)=8; sizeof(unsigned)=4;
76
-  //#define wchar_t uint32_t
77
-  #define wchar_t size_t
78
-
79
-  #ifndef PRIu32
80
-    #define PRIu32 "lu"
81
-  #endif
82
-  #ifndef PRIX32
83
-    #define PRIX32 "lX"
84
-  #endif
85
-
86
-#endif
87
-
88
-#define UNUSED_VARIABLE(a) ((void)(a))
89
-
90
-#ifndef MIN
91
-  #define MIN(a,b) (((a)>(b))?(b):(a))
92
-#endif
23
+// there's overflow of the wchar_t due to the 2-byte size in Arduino
24
+// sizeof(wchar_t)=2; sizeof(size_t)=2; sizeof(uint32_t)=4;
25
+// sizeof(int)=2; sizeof(long)=4; sizeof(unsigned)=2;
26
+//#undef wchar_t
27
+#define wchar_t uint32_t
28
+//typedef uint32_t wchar_t;
93 29
 
94 30
 #ifndef NUM_ARRAY
95 31
   #define NUM_ARRAY(a) (sizeof(a)/sizeof((a)[0]))
96 32
 #endif // NUM_ARRAY
97 33
 
98
-
99
-#ifdef __cplusplus
100
-extern "C" {
101
-#endif
102
-
103
-//#define pixel_len_t u8g_uint_t
104
-#define pixel_len_t uint16_t
105
-//#define pixel_len_t uint8_t
106
-//typedef uint16_t pixel_len_t;
34
+typedef uint16_t pixel_len_t;
107 35
 #define PIXEL_LEN_NOLIMIT ((pixel_len_t)(-1))
108 36
 
37
+/* Perform binary search */
109 38
 typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin); /*"data_list[idx] - *data_pin"*/
110 39
 int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx);
111 40
 
112
-//wchar_t get_val_utf82uni(uint8_t *pstart);
113
-//uint8_t * get_utf8_value(uint8_t *pstart, wchar_t *pval);
114
-uint8_t * get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
41
+/* Get the character, decoding multibyte UTF8 characters and returning a pointer to the start of the next UTF8 character */
42
+uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
115 43
 
44
+/* Returns lenght of string in CHARACTERS, NOT BYTES */
116 45
 uint8_t utf8_strlen(const char *pstart);
117 46
 uint8_t utf8_strlen_P(const char *pstart);
118 47
 
119
-char * utf8_strncpy(char * destination, const char * source, size_t num);
120
-char * utf8_strncpy_P(char * destination, const char * source, size_t num);
121
-int my_strlen_P(const char *pstart);
122
-
123
-#if 0 // DEBUG
124
-#if 0 //defined(ARDUINO)
125
-#if defined(__AVR__)
126
-#define TRACE(fmt, ...) {static const PROGMEM char CONSTSTR[] = "%d %d " fmt " {ln:%d;}\n"; serial_printf_P(CONSTSTR, millis(), ##__VA_ARGS__, __LINE__);  }
127
-#else
128
-#define TRACE(fmt, ...) {static const PROGMEM char CONSTSTR[] = "%d " fmt " {ln:%d, fn:" __FILE__ "}\n"; serial_printf_P(CONSTSTR, millis(), ##__VA_ARGS__, __LINE__);  }
129
-#endif
130
-#define FU_ASSERT(a) if (!(a)) {TRACE("Assert: " # a ); }
131
-
132
-#ifdef __cplusplus
133
-extern "C" {
134
-#endif
135
-void serial_printf_P(const char *format, ...);
136
-#ifdef __cplusplus
137
-}
138
-#endif
139
-
140
-#else // ARDUINO
141
-#include <stdio.h>
142
-#define FU_ASSERT(a) if (!(a)) {printf("Assert: " # a); exit(1);}
143
-#define TRACE(fmt, ...) fprintf(stdout, "[%s()] " fmt " {ln:%d, fn:" __FILE__ "}\n", __func__, ##__VA_ARGS__, __LINE__)
144
-//#else
145
-//#define FU_ASSERT(a)
146
-//#define TRACE(...)
147
-#endif // ARDUINO
148
-
149
-#else // DEBUG
150
-  #define TRACE(fmt, ...)
151
-  #define FU_ASSERT(a)
152
-#endif // DEBUG
153
-
154
-
155
-#ifdef __cplusplus
156
-}
157
-#endif
158
-
159 48
 #endif // _FONT_UTILS_H

+ 3
- 11
Marlin/src/lcd/lcdprint.h ファイルの表示

@@ -17,11 +17,7 @@
17 17
   #include "u8g_fontutf8.h"
18 18
 #endif
19 19
 
20
-#define PRINTABLE(C) (((C) & 0xC0u) != 0x80u)
21
-
22
-#ifdef __cplusplus
23
-  extern "C" {
24
-#endif
20
+#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u)
25 21
 
26 22
 int lcd_glyph_height(void);
27 23
 
@@ -49,15 +45,11 @@ int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length);
49 45
  *
50 46
  * Draw a ROM UTF-8 string
51 47
  */
52
-int lcd_put_u8str_max_rom(const char * utf8_str_P, pixel_len_t max_length);
48
+int lcd_put_u8str_max_P(const char * utf8_str_P, pixel_len_t max_length);
53 49
 
54 50
 void lcd_moveto(int col, int row);
55 51
 
56
-#ifdef __cplusplus
57
-  }
58
-#endif
59
-
60
-#define lcd_put_u8str_rom(str) lcd_put_u8str_max_rom(str, PIXEL_LEN_NOLIMIT)
52
+inline int lcd_put_u8str_P(const char *str) { return lcd_put_u8str_max_P(str, PIXEL_LEN_NOLIMIT); }
61 53
 
62 54
 inline int lcd_put_u8str(const char* str) { return lcd_put_u8str_max(str, PIXEL_LEN_NOLIMIT); }
63 55
 

+ 30
- 77
Marlin/src/lcd/lcdprint_hd44780.cpp ファイルの表示

@@ -24,20 +24,13 @@
24 24
 #include "fontutils.h"
25 25
 #include "lcdprint.h"
26 26
 
27
-#if defined(ARDUINO)
28
-  #include "ultralcd_common_HD44780.h"
29
-  #ifndef LCD_CLASS
30
-    #include <LiquidCrystal.h>
31
-    #define LCD_CLASS LiquidCrystal
32
-  #endif
33
-  extern LCD_CLASS lcd;
34
-  LCD_CLASS *plcd = &lcd;
35
-  #define _lcd_write(a) plcd->write(a)
36
-  #define _lcd_setcursor(col, row) plcd->setCursor((col), (row));
37
-#else
38
-  #define _lcd_write(a) TRACE("Write LCD: %c (%d)", (a), (int)(a));
39
-  #define _lcd_setcursor(col, row) TRACE("Set cursor LCD: (%d,%d)", (col), (row));
27
+#include "ultralcd_common_HD44780.h"
28
+#ifndef LCD_CLASS
29
+  #include <LiquidCrystal.h>
30
+  #define LCD_CLASS LiquidCrystal
40 31
 #endif
32
+extern LCD_CLASS lcd;
33
+LCD_CLASS *plcd = &lcd;
41 34
 
42 35
 int lcd_glyph_height(void) { return 1; }
43 36
 
@@ -878,25 +871,10 @@ static const hd44780_charmap_t g_hd44780_charmap_common[] PROGMEM = {
878 871
 
879 872
 /* return v1 - v2 */
880 873
 static int hd44780_charmap_compare(hd44780_charmap_t * v1, hd44780_charmap_t * v2) {
881
-  FU_ASSERT(NULL != v1);
882
-  FU_ASSERT(NULL != v2);
883
-  TRACE("compare char1 %" PRIu32 "(0x%" PRIX32 ")", v1->uchar, v1->uchar);
884
-  TRACE("compare char2 %" PRIu32 "(0x%" PRIX32 ")", v2->uchar, v2->uchar);
885
-  if (v1->uchar < v2->uchar) {
886
-    TRACE("compare return -1");
874
+  if (v1->uchar < v2->uchar)
887 875
     return -1;
888
-  } else if (v1->uchar > v2->uchar) {
889
-    TRACE("compare return 1");
876
+  else if (v1->uchar > v2->uchar)
890 877
     return 1;
891
-  }
892
-  #if 0
893
-    if (v1->idx < v2->idx) {
894
-      return -1;
895
-    } else if (v1->idx > v2->idx) {
896
-      return 1;
897
-    }
898
-  #endif
899
-  TRACE("compare return 0");
900 878
   return 0;
901 879
 }
902 880
 
@@ -909,9 +887,7 @@ static int pf_bsearch_cb_comp_hd4map_pgm(void *userdata, size_t idx, void * data
909 887
 
910 888
 #if DEBUG
911 889
 
912
-int
913
-test_hd44780_charmap(hd44780_charmap_t *data, size_t size, char *name, char flg_show_contents)
914
-{
890
+int test_hd44780_charmap(hd44780_charmap_t *data, size_t size, char *name, char flg_show_contents) {
915 891
   int ret;
916 892
   size_t idx = 0;
917 893
   hd44780_charmap_t preval = {0, 0, 0};
@@ -963,9 +939,7 @@ test_hd44780_charmap(hd44780_charmap_t *data, size_t size, char *name, char flg_
963 939
   return 0;
964 940
 }
965 941
 
966
-int
967
-test_hd44780_charmap_all(void)
968
-{
942
+int test_hd44780_charmap_all(void) {
969 943
   int flg_error = 0;
970 944
   if (test_hd44780_charmap(g_hd44780_charmap_device, NUM_ARRAY(g_hd44780_charmap_device), "g_hd44780_charmap_device", 0) < 0) {
971 945
     flg_error = 1;
@@ -986,18 +960,17 @@ test_hd44780_charmap_all(void)
986 960
 #endif // DEBUG
987 961
 
988 962
 void lcd_moveto(int col, int row) {
989
-  TRACE("Move to: (%d,%d)", col, row);
990
-  _lcd_setcursor(col, row);
963
+  plcd->setCursor(col, row);
991 964
 }
992 965
 
993 966
 // return < 0 on error
994 967
 // return the advanced cols
995 968
 int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
969
+
996 970
   // find the HD44780 internal ROM first
997 971
   int ret;
998 972
   size_t idx = 0;
999 973
   hd44780_charmap_t pinval;
1000
-  hd44780_charmap_t localval;
1001 974
   hd44780_charmap_t *copy_address = NULL;
1002 975
   pinval.uchar = c;
1003 976
   pinval.idx = -1;
@@ -1006,37 +979,33 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
1006 979
 
1007 980
   // TODO: fix the '\\' that doesnt exist in the HD44870
1008 981
   if (c < 128) {
1009
-    //TRACE("draw char: regular %d", (int)c);
1010
-    _lcd_write((uint8_t)c);
982
+    plcd->write((uint8_t)c);
1011 983
     return 1;
1012 984
   }
1013 985
   copy_address = NULL;
1014 986
   ret = pf_bsearch_r((void *)g_hd44780_charmap_device, NUM_ARRAY(g_hd44780_charmap_device), pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx);
1015 987
   if (ret >= 0) {
1016 988
     copy_address = (hd44780_charmap_t *)(g_hd44780_charmap_device + idx);
1017
-  } else {
989
+  }
990
+  else {
1018 991
     ret = pf_bsearch_r((void *)g_hd44780_charmap_common, NUM_ARRAY(g_hd44780_charmap_common), pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx);
1019
-    if (ret >= 0) {
1020
-      copy_address = (hd44780_charmap_t *)(g_hd44780_charmap_common + idx);
1021
-    }
992
+    if (ret >= 0) copy_address = (hd44780_charmap_t *)(g_hd44780_charmap_common + idx);
1022 993
   }
1023 994
 
1024 995
   if (ret >= 0) {
996
+    hd44780_charmap_t localval;
1025 997
     // found
1026
-    FU_ASSERT(NULL != copy_address);
1027 998
     memcpy_P(&localval, copy_address, sizeof(localval));
1028
-    FU_ASSERT((localval.uchar == c) && (localval.uchar == pinval.uchar));
1029
-    TRACE("draw char: %" PRIu32 "(0x%" PRIX32 ") at ROM %d(+%d)", c, c, (int)localval.idx, (int)localval.idx2);
1030
-    _lcd_write(localval.idx);
999
+    plcd->write(localval.idx);
1031 1000
     if (max_length >= 2 && localval.idx2 > 0) {
1032
-      _lcd_write(localval.idx2);
1001
+      plcd->write(localval.idx2);
1033 1002
       return 2;
1034 1003
     }
1035 1004
     return 1;
1036 1005
   }
1037
-  // print '?' instead
1038
-  TRACE("draw char: Not found " PRIu32 "(0x%" PRIX32 ")", c, c);
1039
-  _lcd_write((uint8_t)'?');
1006
+
1007
+  // Not found, print '?' instead
1008
+  plcd->write((uint8_t)'?');
1040 1009
   return 1;
1041 1010
 }
1042 1011
 
@@ -1044,7 +1013,6 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
1044 1013
 * @brief Draw a UTF-8 string
1045 1014
 *
1046 1015
 * @param utf8_str : the UTF-8 string
1047
-* @param len : the byte length of the string (returned by strlen(utf8_str) or strlen_P(utf8_str) )
1048 1016
 * @param cb_read_byte : the callback function to read one byte from the utf8_str (from RAM or ROM)
1049 1017
 * @param max_length : the pixel length of the string allowed (or number of slots in HD44780)
1050 1018
 *
@@ -1052,39 +1020,24 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
1052 1020
 *
1053 1021
 * Draw a UTF-8 string
1054 1022
 */
1055
-static int lcd_put_u8str_max_cb(const char * utf8_str, uint16_t len, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
1056
-  wchar_t ch;
1057
-  uint8_t *p, *pend;
1023
+static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
1058 1024
   pixel_len_t ret = 0;
1059
-
1060
-  TRACE("BEGIN lcd_put_u8str_max_cb(len=%d, maxlen=%d)", len, max_length);
1061
-  pend = (uint8_t *)utf8_str + len;
1062
-  for (p = (uint8_t *)utf8_str; (p < pend) && (ret < max_length); ) {
1063
-    ch = 0;
1025
+  uint8_t *p = (uint8_t *)utf8_str;
1026
+  while (ret < max_length) {
1027
+    wchar_t ch = 0;
1064 1028
     p = get_utf8_value_cb(p, cb_read_byte, &ch);
1065
-    if (NULL == p) {
1066
-      TRACE("No more char, break ...");
1067
-      break;
1068
-    }
1069
-    FU_ASSERT(ret < max_length);
1029
+    if (!p) break;
1070 1030
     ret += lcd_put_wchar_max(ch, max_length - ret);
1071 1031
   }
1072 1032
   return (int)ret;
1073 1033
 }
1074 1034
 
1075 1035
 int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
1076
-  //TRACE("BEGIN lcd_put_u8str_max(str='%s', len=%d, maxlen=%d)", utf8_str, strlen(utf8_str), max_length);
1077
-  TRACE("BEGIN lcd_put_u8str_max(str='%s')", utf8_str);
1078
-  TRACE("BEGIN lcd_put_u8str_max('len=%d)", strlen(utf8_str));
1079
-  TRACE("BEGIN lcd_put_u8str_max(maxlen=%d)", max_length);
1080
-  return lcd_put_u8str_max_cb(utf8_str, strlen(utf8_str), read_byte_ram, max_length);
1036
+  return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
1081 1037
 }
1082 1038
 
1083
-int lcd_put_u8str_max_rom(const char * utf8_str_P, pixel_len_t max_length) {
1084
-  //TRACE("BEGIN lcd_put_u8str_max_rom('%s', len=%d, maxlen=%d)", utf8_str_P, strlen_P(utf8_str_P), max_length);
1085
-  TRACE("BEGIN lcd_put_u8str_max_rom(len=%d)", strlen_P(utf8_str_P));
1086
-  TRACE("BEGIN lcd_put_u8str_max_rom(maxlen=%d)", max_length);
1087
-  return lcd_put_u8str_max_cb(utf8_str_P, strlen_P(utf8_str_P), read_byte_rom, max_length);
1039
+int lcd_put_u8str_max_P(const char * utf8_str_P, pixel_len_t max_length) {
1040
+  return lcd_put_u8str_max_cb(utf8_str_P, read_byte_rom, max_length);
1088 1041
 }
1089 1042
 
1090 1043
 #endif // DOGLCD

+ 4
- 16
Marlin/src/lcd/lcdprint_u8g.cpp ファイルの表示

@@ -25,25 +25,22 @@ extern U8GLIB *pu8g;
25 25
 
26 26
 int lcd_glyph_height(void) {
27 27
   return u8g_GetFontBBXHeight(pu8g->getU8g());
28
-  //return u8g_GetFontBBXOffY(pu8g->getU8g());
29 28
 }
30 29
 
31 30
 void lcd_moveto(int col, int row) {
32
-  TRACE("Move to: (%d,%d)", col, row);
33 31
   _lcd_setcursor(col, row);
34 32
 }
35 33
 
34
+// return < 0 on error
35
+// return the advanced pixels
36 36
 int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
37 37
   if (c < 256) {
38
-    TRACE("draw char: regular %d", (int)c);
39 38
     _lcd_write((char)c);
40 39
     return u8g_GetFontBBXWidth(pu8g->getU8g());
41 40
   }
42 41
   unsigned int x = pu8g->getPrintCol(),
43 42
                y = pu8g->getPrintRow(),
44 43
                ret = uxg_DrawWchar(pu8g->getU8g(), x, y, c, max_length);
45
-  TRACE("uxg_DrawWchar(x=%d,y=%d,maxlen=%d", x, y, max_length);
46
-  TRACE("u8g->setPrintPos(x=%d + ret=%d,y=%d", x, ret, y);
47 44
   pu8g->setPrintPos(x + ret, y);
48 45
 
49 46
   return ret;
@@ -53,25 +50,16 @@ int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
53 50
   unsigned int x = pu8g->getPrintCol(),
54 51
                y = pu8g->getPrintRow(),
55 52
                ret = uxg_DrawUtf8Str(pu8g->getU8g(), x, y, utf8_str, max_length);
56
-  TRACE("uxg_DrawUtf8Str(x=%d,y=%d,maxlen=%d", x, y, max_length);
57
-  TRACE("u8g->setPrintPos(x=%d + ret=%d,y=%d", x, ret, y);
58 53
   pu8g->setPrintPos(x + ret, y);
59 54
   return ret;
60 55
 }
61 56
 
62
-int lcd_put_u8str_max_rom(const char * utf8_str_P, pixel_len_t max_length) {
57
+int lcd_put_u8str_max_P(const char * utf8_str_P, pixel_len_t max_length) {
63 58
   unsigned int x = pu8g->getPrintCol(),
64 59
                y = pu8g->getPrintRow(),
65 60
                ret = uxg_DrawUtf8StrP(pu8g->getU8g(), x, y, utf8_str_P, max_length);
66
-  TRACE("uxg_DrawUtf8StrP(x=%d,y=%d,maxlen=%d", x, y, max_length);
67
-  TRACE("u8g->setPrintPos(x=%d + ret=%d,y=%d", x, ret, y);
68 61
   pu8g->setPrintPos(x + ret, y);
69 62
   return ret;
70 63
 }
71 64
 
72
-#else // !DOGLCD
73
-
74
-  #define _lcd_write(a) TRACE("Write LCD: %c (%d)", (a), (int)(a));
75
-  #define _lcd_setcursor(col, row) TRACE("Set cursor LCD: (%d,%d)", (col), (row));
76
-
77
-#endif // !DOGLCD
65
+#endif // DOGLCD

+ 26
- 82
Marlin/src/lcd/u8g_fontutf8.cpp ファイルの表示

@@ -18,28 +18,6 @@
18 18
 ////////////////////////////////////////////////////////////
19 19
 typedef void font_t;
20 20
 
21
-#ifndef PSTR
22
-#define PSTR(a) a
23
-
24
-void* memcpy_from_rom(void *dest, const void * rom_src, size_t sz) {
25
-  uint8_t * p;
26
-  uint8_t * s;
27
-
28
-  FU_ASSERT(NULL != dest);
29
-  p = (uint8_t*)dest;
30
-  s = (uint8_t*)rom_src;
31
-  uint8_t c;
32
-  while ((p - (uint8_t *)dest) < sz) {
33
-    *p = pgm_read_byte(s);
34
-    p ++;
35
-    s ++;
36
-  }
37
-  return p;
38
-}
39
-#else
40
-#define memcpy_from_rom memcpy_P
41
-#endif
42
-
43 21
 /**
44 22
  * @brief the callback function to draw something
45 23
  *
@@ -53,25 +31,14 @@ void* memcpy_from_rom(void *dest, const void * rom_src, size_t sz) {
53 31
  */
54 32
 typedef int (* fontgroup_cb_draw_t)(void *userdata, const font_t *fnt_current, const char *msg);
55 33
 
56
-//extern int fontgroup_init(font_group_t * root, const uxg_fontinfo_t * fntinfo, int number);
57
-//extern int fontgroup_drawstring(font_group_t *group, const font_t *fnt_default, const char *utf8_msg, void *userdata, fontgroup_cb_draw_t cb_draw);
58
-//extern uxg_fontinfo_t* fontgroup_first(font_group_t * root);
59
-
60
-
61 34
 ////////////////////////////////////////////////////////////
62 35
 /* return v1 - v2 */
63 36
 static int fontinfo_compare(uxg_fontinfo_t * v1, uxg_fontinfo_t * v2) {
64
-  FU_ASSERT(NULL != v1);
65
-  FU_ASSERT(NULL != v2);
66
-  if (v1->page < v2->page)
67
-    return -1;
68
-  else if (v1->page > v2->page)
69
-    return 1;
37
+  if (v1->page < v2->page)      return -1;
38
+  else if (v1->page > v2->page) return 1;
70 39
 
71
-  if (v1->end < v2->begin)
72
-    return -1;
73
-  else if (v1->begin > v2->end)
74
-    return 1;
40
+  if (v1->end < v2->begin)      return -1;
41
+  else if (v1->begin > v2->end) return 1;
75 42
 
76 43
   return 0;
77 44
 }
@@ -80,7 +47,7 @@ static int fontinfo_compare(uxg_fontinfo_t * v1, uxg_fontinfo_t * v2) {
80 47
 static int pf_bsearch_cb_comp_fntifo_pgm (void *userdata, size_t idx, void *data_pin) {
81 48
   uxg_fontinfo_t *fntinfo = (uxg_fontinfo_t*)userdata;
82 49
   uxg_fontinfo_t localval;
83
-  memcpy_from_rom(&localval, fntinfo + idx, sizeof(localval));
50
+  memcpy_P(&localval, fntinfo + idx, sizeof(localval));
84 51
   return fontinfo_compare(&localval, (uxg_fontinfo_t*)data_pin);
85 52
 }
86 53
 
@@ -92,7 +59,6 @@ typedef struct _font_group_t {
92 59
 static int fontgroup_init(font_group_t * root, const uxg_fontinfo_t * fntinfo, int number) {
93 60
   root->m_fntifo = fntinfo;
94 61
   root->m_fntinfo_num = number;
95
-
96 62
   return 0;
97 63
 }
98 64
 
@@ -105,26 +71,23 @@ static const font_t* fontgroup_find(font_group_t * root, wchar_t val) {
105 71
   if (pf_bsearch_r((void*)root->m_fntifo, root->m_fntinfo_num, pf_bsearch_cb_comp_fntifo_pgm, (void*)&vcmp, &idx) < 0)
106 72
     return NULL;
107 73
 
108
-  memcpy_from_rom(&vcmp, root->m_fntifo + idx, sizeof(vcmp));
74
+  memcpy_P(&vcmp, root->m_fntifo + idx, sizeof(vcmp));
109 75
   return vcmp.fntdata;
110 76
 }
111 77
 
112 78
 static void fontgroup_drawwchar(font_group_t *group, const font_t *fnt_default, wchar_t val, void * userdata, fontgroup_cb_draw_t cb_draw_ram) {
113 79
   uint8_t buf[2] = {0, 0};
114
-  const font_t * fntpqm = NULL;
115
-
116
-  TRACE("fontgroup_drawwchar char=%d(0x%X)", (int)val, (int)val);
117
-  fntpqm = (font_t*)fontgroup_find(group, val);
118
-  if (NULL == fntpqm) {
80
+  const font_t * fntpqm = (font_t*)fontgroup_find(group, val);
81
+  if (!fntpqm) {
82
+    // Unknown char, use default font
119 83
     buf[0] = (uint8_t)(val & 0xFF);
120 84
     fntpqm = fnt_default;
121
-    TRACE("Unknown char %d(0x%X), use default font", (int)val, (int)val);
122 85
   }
123 86
   if (fnt_default != fntpqm) {
124 87
     buf[0] = (uint8_t)(val & 0x7F);
125 88
     buf[0] |= 0x80; // use upper page to avoid 0x00 error in C. you may want to generate the font data
126 89
   }
127
-  //TRACE("set font: %p; (default=%p)", fntpqm, UXG_DEFAULT_FONT);
90
+
128 91
   cb_draw_ram (userdata, fntpqm, (char*) buf);
129 92
 }
130 93
 
@@ -142,31 +105,27 @@ static void fontgroup_drawwchar(font_group_t *group, const font_t *fnt_default,
142 105
  *
143 106
  * Get the screen pixel width of a ROM UTF-8 string
144 107
  */
145
-static void fontgroup_drawstring(font_group_t *group, const font_t *fnt_default, const char *utf8_msg, int len_msg, read_byte_cb_t cb_read_byte, void * userdata, fontgroup_cb_draw_t cb_draw_ram) {
146
-  uint8_t *pend = (uint8_t*)utf8_msg + len_msg;
147
-  for (uint8_t *p = (uint8_t*)utf8_msg; p < pend; ) {
108
+static void fontgroup_drawstring(font_group_t *group, const font_t *fnt_default, const char *utf8_msg, read_byte_cb_t cb_read_byte, void * userdata, fontgroup_cb_draw_t cb_draw_ram) {
109
+  uint8_t *p = (uint8_t*)utf8_msg;
110
+  for (;;) {
148 111
     wchar_t val = 0;
149 112
     p = get_utf8_value_cb(p, cb_read_byte, &val);
150
-    if (NULL == p) {
151
-      TRACE("No more char, break ...");
152
-      break;
153
-    }
113
+    if (!val) break;
154 114
     fontgroup_drawwchar(group, fnt_default, val, userdata, cb_draw_ram);
155 115
   }
156 116
 }
157 117
 
158 118
 ////////////////////////////////////////////////////////////
159
-static char flag_fontgroup_inited1 = 0;
160
-#define flag_fontgroup_inited flag_fontgroup_inited1
119
+static bool flag_fontgroup_was_inited = false;
161 120
 static font_group_t g_fontgroup_root = {NULL, 0};
162 121
 
163 122
 /**
164 123
  * @brief check if font is loaded
165 124
  */
166
-char uxg_Utf8FontIsInited(void) { return flag_fontgroup_inited; }
125
+static inline bool uxg_Utf8FontIsInited(void) { return flag_fontgroup_was_inited; }
167 126
 
168 127
 int uxg_SetUtf8Fonts (const uxg_fontinfo_t * fntinfo, int number) {
169
-  flag_fontgroup_inited = 1;
128
+  flag_fontgroup_was_inited = 1;
170 129
   return fontgroup_init(&g_fontgroup_root, fntinfo, number);
171 130
 }
172 131
 
@@ -179,22 +138,17 @@ struct _uxg_drawu8_data_t {
179 138
   const void * fnt_prev;
180 139
 };
181 140
 
182
-static int fontgroup_cb_draw_u8g (void *userdata, const font_t *fnt_current, const char *msg) {
141
+static int fontgroup_cb_draw_u8g(void *userdata, const font_t *fnt_current, const char *msg) {
183 142
   struct _uxg_drawu8_data_t * pdata = (_uxg_drawu8_data_t*)userdata;
184 143
 
185
-  FU_ASSERT(NULL != userdata);
186 144
   if (pdata->fnt_prev != fnt_current) {
187 145
     u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current);
188 146
     //u8g_SetFontPosBottom(pdata->pu8g);
189 147
     pdata->fnt_prev = fnt_current;
190 148
   }
191
-  if ((pdata->max_width != PIXEL_LEN_NOLIMIT) && (pdata->adv + u8g_GetStrPixelWidth(pdata->pu8g, (char*)msg) > pdata->max_width)) {
192
-    TRACE("return end, adv=%d, width=%d, maxlen=%d", pdata->adv, u8g_GetStrPixelWidth(pdata->pu8g, (char*)msg), pdata->max_width);
149
+  if ((pdata->max_width != PIXEL_LEN_NOLIMIT) && (pdata->adv + u8g_GetStrPixelWidth(pdata->pu8g, (char*)msg) > pdata->max_width))
193 150
     return 1;
194
-  }
195
-  TRACE("Draw string 0x%X", (int)msg[0]);
196 151
   pdata->adv += u8g_DrawStr(pdata->pu8g, pdata->x + pdata->adv, pdata->y, (char*) msg);
197
-  //TRACE("adv pos= %d", pdata->adv);
198 152
   return 0;
199 153
 }
200 154
 
@@ -260,7 +214,7 @@ unsigned int uxg_DrawUtf8Str(u8g_t *pu8g, unsigned int x, unsigned int y, const
260 214
   data.adv = 0;
261 215
   data.max_width = max_width;
262 216
   data.fnt_prev = NULL;
263
-  fontgroup_drawstring(group, fnt_default, utf8_msg, strlen(utf8_msg), read_byte_ram, (void*)&data, fontgroup_cb_draw_u8g);
217
+  fontgroup_drawstring(group, fnt_default, utf8_msg, read_byte_ram, (void*)&data, fontgroup_cb_draw_u8g);
264 218
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
265 219
 
266 220
   return data.adv;
@@ -285,7 +239,6 @@ unsigned int uxg_DrawUtf8StrP(u8g_t *pu8g, unsigned int x, unsigned int y, const
285 239
   const font_t *fnt_default = uxg_GetFont(pu8g);
286 240
 
287 241
   if (!uxg_Utf8FontIsInited()) {
288
-    TRACE("Error, utf8string not inited!");
289 242
     u8g_DrawStrP(pu8g, x, y, (const u8g_pgm_uint8_t *)PSTR("Err: utf8 font not initialized."));
290 243
     return 0;
291 244
   }
@@ -295,19 +248,15 @@ unsigned int uxg_DrawUtf8StrP(u8g_t *pu8g, unsigned int x, unsigned int y, const
295 248
   data.adv = 0;
296 249
   data.max_width = max_width;
297 250
   data.fnt_prev = NULL;
298
-  TRACE("call fontgroup_drawstring");
299
-  fontgroup_drawstring(group, fnt_default, utf8_msg, my_strlen_P(utf8_msg), read_byte_rom, (void*)&data, fontgroup_cb_draw_u8g);
300
-  TRACE("restore font");
251
+  fontgroup_drawstring(group, fnt_default, utf8_msg, read_byte_rom, (void*)&data, fontgroup_cb_draw_u8g);
301 252
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
302 253
 
303
-  TRACE("return %d", data.adv);
304 254
   return data.adv;
305 255
 }
306 256
 
307 257
 static int fontgroup_cb_draw_u8gstrlen(void *userdata, const font_t *fnt_current, const char *msg) {
308 258
   struct _uxg_drawu8_data_t * pdata = (_uxg_drawu8_data_t*)userdata;
309 259
 
310
-  FU_ASSERT(NULL != userdata);
311 260
   if (pdata->fnt_prev != fnt_current) {
312 261
     u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current);
313 262
     u8g_SetFontPosBottom(pdata->pu8g);
@@ -332,15 +281,12 @@ int uxg_GetUtf8StrPixelWidth(u8g_t *pu8g, const char *utf8_msg) {
332 281
   font_group_t *group = &g_fontgroup_root;
333 282
   const font_t *fnt_default = uxg_GetFont(pu8g);
334 283
 
335
-  if (!uxg_Utf8FontIsInited()) {
336
-    TRACE("Err: utf8 font not initialized.");
337
-    return -1;
338
-  }
284
+  if (!uxg_Utf8FontIsInited()) return -1;
339 285
 
340 286
   memset(&data, 0, sizeof(data));
341 287
   data.pu8g = pu8g;
342 288
   data.adv = 0;
343
-  fontgroup_drawstring(group, fnt_default, utf8_msg, strlen(utf8_msg), read_byte_ram, (void*)&data, fontgroup_cb_draw_u8gstrlen);
289
+  fontgroup_drawstring(group, fnt_default, utf8_msg, read_byte_ram, (void*)&data, fontgroup_cb_draw_u8gstrlen);
344 290
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
345 291
 
346 292
   return data.adv;
@@ -361,14 +307,12 @@ int uxg_GetUtf8StrPixelWidthP(u8g_t *pu8g, const char *utf8_msg) {
361 307
   font_group_t *group = &g_fontgroup_root;
362 308
   const font_t *fnt_default = uxg_GetFont(pu8g);
363 309
 
364
-  if (!uxg_Utf8FontIsInited()) {
365
-    TRACE("Err: utf8 font not initialized.");
366
-    return -1;
367
-  }
310
+  if (!uxg_Utf8FontIsInited()) return -1;
311
+
368 312
   memset(&data, 0, sizeof(data));
369 313
   data.pu8g = pu8g;
370 314
   data.adv = 0;
371
-  fontgroup_drawstring(group, fnt_default, utf8_msg, my_strlen_P(utf8_msg), read_byte_rom, (void*)&data, fontgroup_cb_draw_u8gstrlen);
315
+  fontgroup_drawstring(group, fnt_default, utf8_msg, read_byte_rom, (void*)&data, fontgroup_cb_draw_u8gstrlen);
372 316
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
373 317
   return data.adv;
374 318
 }

+ 6
- 16
Marlin/src/lcd/u8g_fontutf8.h ファイルの表示

@@ -12,11 +12,6 @@
12 12
 #include <U8glib.h>
13 13
 #include "fontutils.h"
14 14
 
15
-#ifdef __cplusplus
16
-extern "C" {
17
-#endif
18
-
19
-
20 15
 // the macro to indicate a UTF-8 string
21 16
 // You should to save the C/C++ source in UTF-8 encoding!
22 17
 // Once you change your UTF-8 strings, you need to call the script uxggenpages.sh to create the font data file fontutf8-data.h
@@ -30,21 +25,16 @@ typedef struct _uxg_fontinfo_t {
30 25
     const u8g_fntpgm_uint8_t *fntdata;
31 26
 } uxg_fontinfo_t;
32 27
 
33
-extern int uxg_SetUtf8Fonts (const uxg_fontinfo_t * fntinfo, int number); // fntinfo is type of PROGMEM
34
-extern char uxg_Utf8FontIsInited(void);
28
+int uxg_SetUtf8Fonts (const uxg_fontinfo_t * fntinfo, int number); // fntinfo is type of PROGMEM
35 29
 
36
-extern unsigned int uxg_DrawWchar (u8g_t *pu8g, unsigned int x, unsigned int y, wchar_t ch, pixel_len_t max_length);
30
+unsigned int uxg_DrawWchar (u8g_t *pu8g, unsigned int x, unsigned int y, wchar_t ch, pixel_len_t max_length);
37 31
 
38
-extern unsigned int uxg_DrawUtf8Str (u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, pixel_len_t max_length);
39
-extern unsigned int uxg_DrawUtf8StrP (u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, pixel_len_t max_length);
32
+unsigned int uxg_DrawUtf8Str (u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, pixel_len_t max_length);
33
+unsigned int uxg_DrawUtf8StrP (u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, pixel_len_t max_length);
40 34
 
41
-extern int uxg_GetUtf8StrPixelWidth(u8g_t *pu8g, const char *utf8_msg);
42
-extern int uxg_GetUtf8StrPixelWidthP(u8g_t *pu8g, const char *utf8_msg);
35
+int uxg_GetUtf8StrPixelWidth(u8g_t *pu8g, const char *utf8_msg);
36
+int uxg_GetUtf8StrPixelWidthP(u8g_t *pu8g, const char *utf8_msg);
43 37
 
44 38
 #define uxg_GetFont(puxg) ((puxg)->font)
45 39
 
46
-#ifdef __cplusplus
47
-}
48
-#endif
49
-
50 40
 #endif // _UXG_FONTUTF8_H

+ 42
- 26
Marlin/src/lcd/ultralcd.cpp ファイルの表示

@@ -80,7 +80,7 @@
80 80
   #else
81 81
     #define MAX_MESSAGE_LENGTH CHARSIZE * 2 * (LCD_WIDTH)
82 82
   #endif
83
-  uint8_t status_scroll_pos = 0;
83
+  uint8_t status_scroll_offset = 0;
84 84
 #else
85 85
   #define MAX_MESSAGE_LENGTH CHARSIZE * (LCD_WIDTH)
86 86
 #endif
@@ -5360,30 +5360,8 @@ void lcd_update() {
5360 5360
   } // ELAPSED(ms, next_lcd_update_ms)
5361 5361
 }
5362 5362
 
5363
-inline void pad_message_string() {
5364
-  uint8_t i = 0, j = 0;
5365
-  char c;
5366
-  lcd_status_message[MAX_MESSAGE_LENGTH] = '\0';
5367
-  while ((c = lcd_status_message[i]) && j < LCD_WIDTH) {
5368
-    if (PRINTABLE(c)) j++;
5369
-    i++;
5370
-  }
5371
-  if (true
5372
-    #if ENABLED(STATUS_MESSAGE_SCROLLING)
5373
-      && j < LCD_WIDTH
5374
-    #endif
5375
-  ) {
5376
-    // pad with spaces to fill up the line
5377
-    while (j++ < LCD_WIDTH) lcd_status_message[i++] = ' ';
5378
-    // chop off at the edge
5379
-    lcd_status_message[i] = '\0';
5380
-  }
5381
-}
5382
-
5383 5363
 void lcd_finishstatus(const bool persist=false) {
5384 5364
 
5385
-  pad_message_string();
5386
-
5387 5365
   #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
5388 5366
     UNUSED(persist);
5389 5367
   #endif
@@ -5401,7 +5379,7 @@ void lcd_finishstatus(const bool persist=false) {
5401 5379
   #endif
5402 5380
 
5403 5381
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
5404
-    status_scroll_pos = 0;
5382
+    status_scroll_offset = 0;
5405 5383
   #endif
5406 5384
 }
5407 5385
 
@@ -5413,7 +5391,26 @@ bool lcd_hasstatus() { return (lcd_status_message[0] != '\0'); }
5413 5391
 
5414 5392
 void lcd_setstatus(const char * const message, const bool persist) {
5415 5393
   if (lcd_status_message_level > 0) return;
5416
-  strncpy(lcd_status_message, message, MAX_MESSAGE_LENGTH);
5394
+
5395
+  // Here we have a problem. The message is encoded in UTF8, so
5396
+  // arbitrarily cutting it will be a problem. We MUST be sure
5397
+  // that there is no cutting in the middle of a multibyte character!
5398
+
5399
+  // Get a pointer to the null terminator
5400
+  const char* pend = message + strlen(message);
5401
+
5402
+  //  If length of supplied UTF8 string is greater than
5403
+  // our buffer size, start cutting whole UTF8 chars
5404
+  while ((pend - message) > MAX_MESSAGE_LENGTH) {
5405
+    --pend;
5406
+    while (!START_OF_UTF8_CHAR(*pend)) --pend;
5407
+  };
5408
+
5409
+  // At this point, we have the proper cut point. Use it
5410
+  uint8_t maxLen = pend - message;
5411
+  strncpy(lcd_status_message, message, maxLen);
5412
+  lcd_status_message[maxLen] = '\0';
5413
+
5417 5414
   lcd_finishstatus(persist);
5418 5415
 }
5419 5416
 
@@ -5421,7 +5418,26 @@ void lcd_setstatusPGM(const char * const message, int8_t level) {
5421 5418
   if (level < 0) level = lcd_status_message_level = 0;
5422 5419
   if (level < lcd_status_message_level) return;
5423 5420
   lcd_status_message_level = level;
5424
-  strncpy_P(lcd_status_message, message, MAX_MESSAGE_LENGTH);
5421
+
5422
+  // Here we have a problem. The message is encoded in UTF8, so
5423
+  // arbitrarily cutting it will be a problem. We MUST be sure
5424
+  // that there is no cutting in the middle of a multibyte character!
5425
+
5426
+  // Get a pointer to the null terminator
5427
+  const char* pend = message + strlen_P(message);
5428
+
5429
+  //  If length of supplied UTF8 string is greater than
5430
+  // our buffer size, start cutting whole UTF8 chars
5431
+  while ((pend - message) > MAX_MESSAGE_LENGTH) {
5432
+    --pend;
5433
+    while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend;
5434
+  };
5435
+
5436
+  // At this point, we have the proper cut point. Use it
5437
+  uint8_t maxLen = pend - message;
5438
+  strncpy_P(lcd_status_message, message, maxLen);
5439
+  lcd_status_message[maxLen] = '\0';
5440
+
5425 5441
   lcd_finishstatus(level > 0);
5426 5442
 }
5427 5443
 

+ 8
- 8
Marlin/src/lcd/ultralcd_impl_DOGM.h ファイルの表示

@@ -341,9 +341,9 @@ void lcd_kill_screen() {
341 341
     lcd_moveto(0, h4 * 1);
342 342
     lcd_put_u8str(lcd_status_message);
343 343
     lcd_moveto(0, h4 * 2);
344
-    lcd_put_u8str_rom(PSTR(MSG_HALTED));
344
+    lcd_put_u8str_P(PSTR(MSG_HALTED));
345 345
     lcd_moveto(0, h4 * 3);
346
-    lcd_put_u8str_rom(PSTR(MSG_PLEASE_RESET));
346
+    lcd_put_u8str_P(PSTR(MSG_PLEASE_RESET));
347 347
   } while (u8g.nextPage());
348 348
 }
349 349
 
@@ -415,7 +415,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
415 415
         int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
416 416
         while (--pad >= 0) { lcd_put_wchar(' '); n--; }
417 417
       }
418
-      n -= lcd_put_u8str_max_rom(pstr, n);
418
+      n -= lcd_put_u8str_max_P(pstr, n);
419 419
       if (NULL != valstr) {
420 420
         n -= lcd_put_u8str_max(valstr, n);
421 421
       }
@@ -431,7 +431,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
431 431
     if (lcd_implementation_mark_as_selected(row, isSelected)) {
432 432
       uint8_t n = LCD_WIDTH - (START_COL) - 2;
433 433
       n *= DOG_CHAR_WIDTH;
434
-      n -= lcd_put_u8str_max_rom(pstr, n);
434
+      n -= lcd_put_u8str_max_P(pstr, n);
435 435
       while (n - DOG_CHAR_WIDTH > 0) { n -= lcd_put_wchar(' '); }
436 436
       lcd_moveto(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), row_y2);
437 437
       lcd_put_wchar(post_char);
@@ -451,11 +451,11 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
451 451
       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
452 452
       uint8_t n = LCD_WIDTH - (START_COL) - 2 - vallen;
453 453
       n *= DOG_CHAR_WIDTH;
454
-      n -= lcd_put_u8str_max_rom(pstr, n);
454
+      n -= lcd_put_u8str_max_P(pstr, n);
455 455
       lcd_put_wchar(':');
456 456
       while (n - DOG_CHAR_WIDTH > 0) { n -= lcd_put_wchar(' '); }
457 457
       lcd_moveto(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH) * vallen, row_y2);
458
-      if (pgm) lcd_put_u8str_rom(data); else lcd_put_u8str((char*)data);
458
+      if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str((char*)data);
459 459
     }
460 460
   }
461 461
 
@@ -499,7 +499,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
499 499
     bool onpage = PAGE_CONTAINS(baseline + 1 - (DOG_CHAR_HEIGHT_EDIT), baseline);
500 500
     if (onpage) {
501 501
       lcd_moveto(0, baseline);
502
-      lcd_put_u8str_rom(pstr);
502
+      lcd_put_u8str_P(pstr);
503 503
     }
504 504
 
505 505
     if (value != NULL) {
@@ -641,7 +641,7 @@ void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
641 641
         if (!isnan(ubl.z_values[x_plot][y_plot]))
642 642
           lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot]));
643 643
         else
644
-          lcd_put_u8str_rom(PSTR(" -----"));
644
+          lcd_put_u8str_P(PSTR(" -----"));
645 645
       }
646 646
 
647 647
     }

+ 118
- 52
Marlin/src/lcd/ultralcd_impl_HD44780.h ファイルの表示

@@ -347,26 +347,51 @@ void lcd_implementation_clear() { lcd.clear(); }
347 347
   }
348 348
 
349 349
   // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line
350
-  void lcd_scroll(const int16_t col, const int16_t line, const char* const text, const int16_t len, const int16_t time) {
351
-    #if 1
352
-      lcd_put_u8str(text);
353
-    #else
354
-      char tmp[LCD_WIDTH + 1] = {0};
355
-      int16_t n = MAX(utf8_strlen_P(text) - len, 0);
356
-      for (int16_t i = 0; i <= n; i++) {
357
-        utf8_strncpy_p(tmp, text + i, MIN(len, LCD_WIDTH));
350
+  void lcd_scroll(const uint8_t col, const uint8_t line, const char* const text, const uint8_t len, const int16_t time) {
351
+    uint8_t slen = utf8_strlen_P(text);
352
+    if (slen < len) {
353
+      // Fits into,
354
+      lcd_moveto(col, line);
355
+      lcd_put_u8str_max_P(text, len);
356
+      while (slen < len) {
357
+        lcd_put_wchar(' ');
358
+        ++slen;
359
+      }
360
+      safe_delay(time);
361
+    }
362
+    else {
363
+      const char* p = text;
364
+      int dly = time / MAX(slen, 1);
365
+      for (uint8_t i = 0; i <= slen; i++) {
366
+
367
+        // Go to the correct place
358 368
         lcd_moveto(col, line);
359
-        lcd_put_u8str(tmp);
360
-        delay(time / MAX(n, 1));
369
+
370
+        // Print the text
371
+        lcd_put_u8str_max_P(p, len);
372
+
373
+        // Fill with spaces
374
+        uint8_t ix = slen - i;
375
+        while (ix < len) {
376
+          lcd_put_wchar(' ');
377
+          ++ix;
378
+        }
379
+
380
+        // Delay
381
+        safe_delay(dly);
382
+
383
+        // Advance to the next UTF8 valid position
384
+        p++;
385
+        while (!START_OF_UTF8_CHAR(pgm_read_byte(p))) p++;
361 386
       }
362
-    #endif
387
+    }
363 388
   }
364 389
 
365 390
   static void logo_lines(const char* const extra) {
366 391
     int16_t indent = (LCD_WIDTH - 8 - utf8_strlen_P(extra)) / 2;
367
-    lcd_moveto(indent, 0); lcd_put_wchar('\x00'); lcd_put_u8str_rom(PSTR( "------" ));  lcd_put_wchar('\x01');
368
-    lcd_moveto(indent, 1);                        lcd_put_u8str_rom(PSTR("|Marlin|"));  lcd_put_u8str_rom(extra);
369
-    lcd_moveto(indent, 2); lcd_put_wchar('\x02'); lcd_put_u8str_rom(PSTR( "------" ));  lcd_put_wchar('\x03');
392
+    lcd_moveto(indent, 0); lcd_put_wchar('\x00'); lcd_put_u8str_P(PSTR( "------" ));  lcd_put_wchar('\x01');
393
+    lcd_moveto(indent, 1);                        lcd_put_u8str_P(PSTR("|Marlin|"));  lcd_put_u8str_P(extra);
394
+    lcd_moveto(indent, 2); lcd_put_wchar('\x02'); lcd_put_u8str_P(PSTR( "------" ));  lcd_put_wchar('\x03');
370 395
   }
371 396
 
372 397
   void lcd_bootscreen() {
@@ -379,7 +404,7 @@ void lcd_implementation_clear() { lcd.clear(); }
379 404
       lcd_erase_line(3); \
380 405
       if (utf8_strlen(STRING) <= LCD_WIDTH) { \
381 406
         lcd_moveto((LCD_WIDTH - utf8_strlen_P(PSTR(STRING))) / 2, 3); \
382
-        lcd_put_u8str_rom(PSTR(STRING)); \
407
+        lcd_put_u8str_P(PSTR(STRING)); \
383 408
         safe_delay(DELAY); \
384 409
       } \
385 410
       else { \
@@ -452,10 +477,10 @@ void lcd_kill_screen() {
452 477
     lcd_moveto(0, 2);
453 478
   #else
454 479
     lcd_moveto(0, 2);
455
-    lcd_put_u8str_rom(PSTR(MSG_HALTED));
480
+    lcd_put_u8str_P(PSTR(MSG_HALTED));
456 481
     lcd_moveto(0, 3);
457 482
   #endif
458
-  lcd_put_u8str_rom(PSTR(MSG_PLEASE_RESET));
483
+  lcd_put_u8str_P(PSTR(MSG_PLEASE_RESET));
459 484
 }
460 485
 
461 486
 //
@@ -473,7 +498,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
473 498
     else {
474 499
       #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
475 500
         if (!axis_known_position[axis])
476
-          lcd_put_u8str_rom(axis == Z_AXIS ? PSTR("      ") : PSTR("    "));
501
+          lcd_put_u8str_P(axis == Z_AXIS ? PSTR("      ") : PSTR("    "));
477 502
         else
478 503
       #endif
479 504
           lcd_put_u8str(value);
@@ -634,11 +659,11 @@ static void lcd_implementation_status_screen() {
634 659
 
635 660
       #if ENABLED(SDSUPPORT)
636 661
         lcd_moveto(0, 2);
637
-        lcd_put_u8str_rom(PSTR("SD"));
662
+        lcd_put_u8str_P(PSTR("SD"));
638 663
         if (IS_SD_PRINTING)
639 664
           lcd_put_u8str(itostr3(card.percentDone()));
640 665
         else
641
-          lcd_put_u8str_rom(PSTR("---"));
666
+          lcd_put_u8str_P(PSTR("---"));
642 667
           lcd_put_wchar('%');
643 668
       #endif // SDSUPPORT
644 669
 
@@ -698,11 +723,11 @@ static void lcd_implementation_status_screen() {
698 723
     #if LCD_WIDTH >= 20 && ENABLED(SDSUPPORT)
699 724
 
700 725
       lcd_moveto(7, 2);
701
-      lcd_put_u8str_rom(PSTR("SD"));
726
+      lcd_put_u8str_P(PSTR("SD"));
702 727
       if (IS_SD_PRINTING)
703 728
         lcd_put_u8str(itostr3(card.percentDone()));
704 729
       else
705
-        lcd_put_u8str_rom(PSTR("---"));
730
+        lcd_put_u8str_P(PSTR("---"));
706 731
       lcd_put_wchar('%');
707 732
 
708 733
     #endif // LCD_WIDTH >= 20 && SDSUPPORT
@@ -739,9 +764,9 @@ static void lcd_implementation_status_screen() {
739 764
     // Show Filament Diameter and Volumetric Multiplier %
740 765
     // After allowing lcd_status_message to show for 5 seconds
741 766
     if (ELAPSED(millis(), previous_lcd_status_ms + 5000UL)) {
742
-      lcd_put_u8str_rom(PSTR("Dia "));
767
+      lcd_put_u8str_P(PSTR("Dia "));
743 768
       lcd_put_u8str(ftostr12ns(filament_width_meas));
744
-      lcd_put_u8str_rom(PSTR(" V"));
769
+      lcd_put_u8str_P(PSTR(" V"));
745 770
       lcd_put_u8str(itostr3(100.0 * (
746 771
           parser.volumetric_enabled
747 772
             ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
@@ -756,35 +781,76 @@ static void lcd_implementation_status_screen() {
756 781
 
757 782
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
758 783
     static bool last_blink = false;
759
-    const uint8_t slen = utf8_strlen(lcd_status_message);
760
-    const char *stat = lcd_status_message + status_scroll_pos;
761
-    if (slen <= LCD_WIDTH)
762
-      lcd_put_u8str(stat);                                        // The string isn't scrolling
784
+
785
+    // Get the UTF8 character count of the string
786
+    uint8_t slen = utf8_strlen(lcd_status_message);
787
+
788
+    // If the string fits into the LCD, just print it and do not scroll it
789
+    if (slen <= LCD_WIDTH) {
790
+
791
+      // The string isn't scrolling and may not fill the screen
792
+      lcd_put_u8str(lcd_status_message);
793
+
794
+      // Fill the rest with spaces
795
+      while (slen < LCD_WIDTH) {
796
+        lcd_put_wchar(' ');
797
+        ++slen;
798
+      }
799
+    }
763 800
     else {
764
-      if (status_scroll_pos <= slen - LCD_WIDTH)
765
-        lcd_put_u8str(stat);                                      // The string fills the screen
801
+      // String is larger than the available space in screen.
802
+
803
+      // Get a pointer to the next valid UTF8 character
804
+      const char *stat = lcd_status_message + status_scroll_offset;
805
+
806
+      // Get the string remaining length
807
+      const uint8_t rlen = utf8_strlen(stat);
808
+
809
+      // If we have enough characters to display
810
+      if (rlen >= LCD_WIDTH) {
811
+        // The remaining string fills the screen - Print it
812
+        lcd_put_u8str_max(stat, LCD_WIDTH);
813
+      }
766 814
       else {
767
-        uint8_t chars = LCD_WIDTH;
768
-        if (status_scroll_pos < slen) {                       // First string still visible
769
-          lcd_put_u8str(stat);                                    // The string leaves space
770
-          chars -= slen - status_scroll_pos;                  // Amount of space left
771
-        }
772
-        lcd_put_wchar('.');                                       // Always at 1+ spaces left, draw a dot
773
-        if (--chars) {
774
-          if (status_scroll_pos < slen + 1)                   // Draw a second dot if there's space
775
-            --chars, lcd_put_wchar('.');
776
-          if (chars) lcd_put_u8str_max(lcd_status_message, chars); // Print a second copy of the message
815
+
816
+        // The remaining string does not completely fill the screen
817
+        lcd_put_u8str_max(stat, LCD_WIDTH);               // The string leaves space
818
+        uint8_t chars = LCD_WIDTH - rlen;                 // Amount of space left in characters
819
+
820
+        lcd_put_wchar('.');                               // Always at 1+ spaces left, draw a dot
821
+        if (--chars) {                                    // Draw a second dot if there's space
822
+          lcd_put_wchar('.');
823
+          if (--chars)
824
+            lcd_put_u8str_max(lcd_status_message, chars); // Print a second copy of the message
777 825
         }
778 826
       }
779 827
       if (last_blink != blink) {
780 828
         last_blink = blink;
781
-        // Skip any non-printing bytes
782
-        if (status_scroll_pos < slen) while (!PRINTABLE(lcd_status_message[status_scroll_pos])) status_scroll_pos++;
783
-        if (++status_scroll_pos >= slen + 2) status_scroll_pos = 0;
829
+
830
+        // Adjust by complete UTF8 characters
831
+        if (status_scroll_offset < slen) {
832
+          status_scroll_offset++;
833
+          while (!START_OF_UTF8_CHAR(lcd_status_message[status_scroll_offset]))
834
+            status_scroll_offset++;
835
+        }
836
+        else
837
+          status_scroll_offset = 0;
784 838
       }
785 839
     }
786 840
   #else
787
-    lcd_put_u8str(lcd_status_message);
841
+    UNUSED(blink);
842
+
843
+    // Get the UTF8 character count of the string
844
+    uint8_t slen = utf8_strlen(lcd_status_message);
845
+
846
+    // Just print the string to the LCD
847
+    lcd_put_u8str_max(lcd_status_message, LCD_WIDTH);
848
+
849
+    // Fill the rest with spaces if there are missing spaces
850
+    while (slen < LCD_WIDTH) {
851
+      lcd_put_wchar(' ');
852
+      ++slen;
853
+    }
788 854
   #endif
789 855
 }
790 856
 
@@ -809,7 +875,7 @@ static void lcd_implementation_status_screen() {
809 875
       int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
810 876
       while (--pad >= 0) { lcd_put_wchar(' '); n--; }
811 877
     }
812
-    n -= lcd_put_u8str_max_rom(pstr, n);
878
+    n -= lcd_put_u8str_max_P(pstr, n);
813 879
     if (valstr) n -= lcd_put_u8str_max(valstr, n);
814 880
     for (; n > 0; --n) lcd_put_wchar(' ');
815 881
   }
@@ -818,7 +884,7 @@ static void lcd_implementation_status_screen() {
818 884
     uint8_t n = LCD_WIDTH - 2;
819 885
     lcd_moveto(0, row);
820 886
     lcd_put_wchar(sel ? pre_char : ' ');
821
-    n -= lcd_put_u8str_max_rom(pstr, n);
887
+    n -= lcd_put_u8str_max_P(pstr, n);
822 888
     while (n--) lcd_put_wchar(' ');
823 889
     lcd_put_wchar(post_char);
824 890
   }
@@ -827,7 +893,7 @@ static void lcd_implementation_status_screen() {
827 893
     uint8_t n = LCD_WIDTH - 2 - utf8_strlen(data);
828 894
     lcd_moveto(0, row);
829 895
     lcd_put_wchar(sel ? pre_char : ' ');
830
-    n -= lcd_put_u8str_max_rom(pstr, n);
896
+    n -= lcd_put_u8str_max_P(pstr, n);
831 897
     lcd_put_wchar(':');
832 898
     while (n--) lcd_put_wchar(' ');
833 899
     lcd_put_u8str(data);
@@ -836,10 +902,10 @@ static void lcd_implementation_status_screen() {
836 902
     uint8_t n = LCD_WIDTH - 2 - utf8_strlen_P(data);
837 903
     lcd_moveto(0, row);
838 904
     lcd_put_wchar(sel ? pre_char : ' ');
839
-    n -= lcd_put_u8str_max_rom(pstr, n);
905
+    n -= lcd_put_u8str_max_P(pstr, n);
840 906
     lcd_put_wchar(':');
841 907
     while (n--) lcd_put_wchar(' ');
842
-    lcd_put_u8str_rom(data);
908
+    lcd_put_u8str_P(data);
843 909
   }
844 910
 
845 911
   #define DRAWMENU_SETTING_EDIT_GENERIC(_src) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', _src)
@@ -847,7 +913,7 @@ static void lcd_implementation_status_screen() {
847 913
 
848 914
   void lcd_implementation_drawedit(const char* pstr, const char* const value=NULL) {
849 915
     lcd_moveto(1, 1);
850
-    lcd_put_u8str_rom(pstr);
916
+    lcd_put_u8str_P(pstr);
851 917
     if (value != NULL) {
852 918
       lcd_put_wchar(':');
853 919
       int len = utf8_strlen(value);
@@ -1293,7 +1359,7 @@ static void lcd_implementation_status_screen() {
1293 1359
         if (!isnan(ubl.z_values[x][inverted_y]))
1294 1360
           lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1295 1361
         else
1296
-          lcd_put_u8str_rom(PSTR(" -----"));
1362
+          lcd_put_u8str_P(PSTR(" -----"));
1297 1363
 
1298 1364
       #else                 // 16x4 or 20x4 display
1299 1365
 
@@ -1312,7 +1378,7 @@ static void lcd_implementation_status_screen() {
1312 1378
         if (!isnan(ubl.z_values[x][inverted_y]))
1313 1379
           lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1314 1380
         else
1315
-          lcd_put_u8str_rom(PSTR(" -----"));
1381
+          lcd_put_u8str_P(PSTR(" -----"));
1316 1382
 
1317 1383
       #endif // LCD_HEIGHT > 3
1318 1384
     }

+ 5
- 15
frameworks/CMSIS/LPC1768/lib/usb/usbhw.cpp ファイルの表示

@@ -563,8 +563,7 @@ uint32_t USB_DMA_Status (uint32_t EPNum) {
563 563
   uint32_t ptr, val;
564 564
 
565 565
   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
566
-  if (ptr == 0)
567
-	return (USB_DMA_INVALID);
566
+  if (ptr == 0) return (USB_DMA_INVALID);
568 567
 
569 568
   val = *((uint32_t *)(ptr + 3*4));            /* Status Information */
570 569
   switch ((val >> 1) & 0x0F) {
@@ -596,13 +595,8 @@ uint32_t USB_DMA_Status (uint32_t EPNum) {
596 595
 
597 596
 uint32_t USB_DMA_BufAdr (uint32_t EPNum) {
598 597
   uint32_t ptr, val;
599
-
600 598
   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
601
-  if (ptr == 0)
602
-  {
603
-	return ((uint32_t)(-1));                /* DMA Invalid */
604
-  }
605
-
599
+  if (ptr == 0) return ((uint32_t)(-1));    /* DMA Invalid */
606 600
   val = *((uint32_t *)(ptr + 2*4));         /* Buffer Address */
607 601
   return (val);                             /* Current Address */
608 602
 }
@@ -619,12 +613,8 @@ uint32_t USB_DMA_BufAdr (uint32_t EPNum) {
619 613
 
620 614
 uint32_t USB_DMA_BufCnt (uint32_t EPNum) {
621 615
   uint32_t ptr, val;
622
-
623 616
   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
624
-  if (ptr == 0)
625
-  {
626
-	return ((uint32_t)(-1));                /* DMA Invalid */
627
-  }
617
+  if (ptr == 0) return ((uint32_t)(-1));    /* DMA Invalid */
628 618
   val = *((uint32_t *)(ptr + 3*4));         /* Status Information */
629 619
   return (val >> 16);                       /* Current Count */
630 620
 }
@@ -695,7 +685,7 @@ void USB_IRQHandler (void) {
695 685
 #if USB_SOF_EVENT
696 686
   /* Start of Frame Interrupt */
697 687
   if (disr & FRAME_INT) {
698
-	LPC_USB->USBDevIntClr = FRAME_INT;
688
+    LPC_USB->USBDevIntClr = FRAME_INT;
699 689
     USB_SOF_Event();
700 690
   }
701 691
 #endif
@@ -703,7 +693,7 @@ void USB_IRQHandler (void) {
703 693
 #if USB_ERROR_EVENT
704 694
   /* Error Interrupt */
705 695
   if (disr & ERR_INT) {
706
-	LPC_USB->USBDevIntClr = ERR_INT;
696
+    LPC_USB->USBDevIntClr = ERR_INT;
707 697
     WrCmd(CMD_RD_ERR_STAT);
708 698
     val = RdCmdDat(DAT_RD_ERR_STAT);
709 699
     USB_Error_Event(val);

読み込み中…
キャンセル
保存