ソースを参照

[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
     // away. When clock is not known, use a loop instead, which generates
162
     // away. When clock is not known, use a loop instead, which generates
163
     // shorter code.
163
     // shorter code.
164
     if (__builtin_constant_p(spiClock)) {
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
       uint32_t clockSetting = F_CPU / 2;
174
       uint32_t clockSetting = F_CPU / 2;
182
       clockDiv = 0;
175
       clockDiv = 0;
183
       while (clockDiv < 6 && spiClock < clockSetting) {
176
       while (clockDiv < 6 && spiClock < clockSetting) {
187
     }
180
     }
188
 
181
 
189
     // Compensate for the duplicate fosc/64
182
     // Compensate for the duplicate fosc/64
190
-    if (clockDiv == 6)
191
-      clockDiv = 7;
183
+    if (clockDiv == 6) clockDiv = 7;
192
 
184
 
193
     // Invert the SPI2X bit
185
     // Invert the SPI2X bit
194
     clockDiv ^= 0x1;
186
     clockDiv ^= 0x1;

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

56
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
56
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
57
 
57
 
58
 #if ENABLED(ULTRA_LCD)
58
 #if ENABLED(ULTRA_LCD)
59
-  extern char lcd_status_message[];
60
   void lcd_quick_feedback(const bool clear_buttons);
59
   void lcd_quick_feedback(const bool clear_buttons);
61
 #endif
60
 #endif
62
 
61
 

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

135
 
135
 
136
 // External references
136
 // External references
137
 
137
 
138
-#if ENABLED(ULTRA_LCD)
139
-  extern char lcd_status_message[];
140
-#endif
141
-
142
 // Private functions
138
 // Private functions
143
 
139
 
144
 static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
140
 static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
508
 
504
 
509
       wait_for_release();
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
       lcd_setstatusPGM(PSTR("Done Priming"), 99);
507
       lcd_setstatusPGM(PSTR("Done Priming"), 99);
514
       lcd_quick_feedback(true);
508
       lcd_quick_feedback(true);
515
       lcd_external_control = false;
509
       lcd_external_control = false;

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

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

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

33
   const char * const str = itostr3(temp);
33
   const char * const str = itostr3(temp);
34
   lcd_moveto(x - (str[0] != ' ' ? 0 : str[1] != ' ' ? 1 : 2) * DOG_CHAR_WIDTH / 2, y);
34
   lcd_moveto(x - (str[0] != ' ' ? 0 : str[1] != ' ' ? 1 : 2) * DOG_CHAR_WIDTH / 2, y);
35
   lcd_put_u8str(str);
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
 #ifndef HEAT_INDICATOR_X
39
 #ifndef HEAT_INDICATOR_X
113
     else {
113
     else {
114
       #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
114
       #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
115
         if (!axis_known_position[axis])
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
         else
117
         else
118
       #endif
118
       #endif
119
           lcd_put_u8str(value);
119
           lcd_put_u8str(value);
124
 inline void lcd_implementation_status_message(const bool blink) {
124
 inline void lcd_implementation_status_message(const bool blink) {
125
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
125
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
126
     static bool last_blink = false;
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
     else {
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
       else {
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
       if (last_blink != blink) {
171
       if (last_blink != blink) {
148
         last_blink = blink;
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
   #else
184
   #else
155
     UNUSED(blink);
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
   #endif
198
   #endif
158
 }
199
 }
159
 
200
 
417
       lcd_put_wchar('%');
458
       lcd_put_wchar('%');
418
       lcd_setFont(FONT_MENU);
459
       lcd_setFont(FONT_MENU);
419
       lcd_moveto(47, 50);
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
       lcd_moveto(93, 50);
462
       lcd_moveto(93, 50);
422
       lcd_put_wchar(LCD_STR_FILAM_MUL[0]);
463
       lcd_put_wchar(LCD_STR_FILAM_MUL[0]);
423
     #endif
464
     #endif
437
         lcd_implementation_status_message(blink);
478
         lcd_implementation_status_message(blink);
438
       }
479
       }
439
       else {
480
       else {
440
-        lcd_put_u8str_rom(PSTR(LCD_STR_FILAM_DIA));
481
+        lcd_put_u8str_P(PSTR(LCD_STR_FILAM_DIA));
441
         lcd_put_wchar(':');
482
         lcd_put_wchar(':');
442
         lcd_put_u8str(wstring);
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
         lcd_put_wchar(':');
485
         lcd_put_wchar(':');
445
         lcd_put_u8str(mstring);
486
         lcd_put_u8str(mstring);
446
         lcd_put_wchar('%');
487
         lcd_put_wchar('%');

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

615
 void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
615
 void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
616
   set_ddram_address(DDRAM_LINE_4);
616
   set_ddram_address(DDRAM_LINE_4);
617
   begin_data();
617
   begin_data();
618
+  const uint8_t lcd_len = 16;
618
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
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
       write_str(str);
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
     else {
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
       else
668
       else
644
-        status_scroll_pos++;
669
+        status_scroll_offset = 0;
645
     }
670
     }
646
   #else
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
   #endif
683
   #endif
649
 }
684
 }
650
 
685
 
792
    */
827
    */
793
   if (forceUpdate || status_changed()) {
828
   if (forceUpdate || status_changed()) {
794
     #if ENABLED(STATUS_MESSAGE_SCROLLING)
829
     #if ENABLED(STATUS_MESSAGE_SCROLLING)
795
-      status_scroll_pos = 0;
830
+      status_scroll_offset = 0;
796
     #endif
831
     #endif
797
     #if STATUS_EXPIRE_SECONDS
832
     #if STATUS_EXPIRE_SECONDS
798
       countdown = lcd_status_message[0] ? STATUS_EXPIRE_SECONDS : 0;
833
       countdown = lcd_status_message[0] ? STATUS_EXPIRE_SECONDS : 0;

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

16
 
16
 
17
 #include "fontutils.h"
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
  * @brief Using binary search to find the position by data_pin
28
  * @brief Using binary search to find the position by data_pin
71
  *
29
  *
82
 int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx) {
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
   int retcomp;
41
   int retcomp;
84
 
42
 
85
-  FU_ASSERT(NULL != ret_idx);
86
-  /* 查找合适的位置 */
87
   if (num_data < 1) {
43
   if (num_data < 1) {
88
     *ret_idx = 0;
44
     *ret_idx = 0;
89
-    DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_ERROR, "num_data(%" PRIuSZ ") < 1", num_data);
90
     return -1;
45
     return -1;
91
   }
46
   }
92
 
47
 
93
-  /* 折半查找 */
94
-  /* 为了不出现负数,以免缩小索引的所表示的数据范围
95
-   * (负数表明减少一位二进制位的使用),
96
-   * 内部 ileft 和 iright使用从1开始的下标,
97
-   *   即1表示C语言中的0, 2表示语言中的1,以此类推。
98
-   * 对外还是使用以 0 为开始的下标
99
-   */
100
   size_t i = 0, ileft = 1, iright = num_data;
48
   size_t i = 0, ileft = 1, iright = num_data;
101
   bool flg_found = false;
49
   bool flg_found = false;
102
   for (; ileft <= iright;) {
50
   for (; ileft <= iright;) {
122
     *ret_idx = i;
70
     *ret_idx = i;
123
   else if (ileft >= i + 2)
71
   else if (ileft >= i + 2)
124
     *ret_idx = i + 1;
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
   return -1;
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
 uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
78
 uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
141
   uint32_t val = 0;
79
   uint32_t val = 0;
142
   uint8_t *p = pstart;
80
   uint8_t *p = pstart;
143
 
81
 
144
-  FU_ASSERT(NULL != pstart);
145
-  FU_ASSERT(NULL != cb_read_byte);
146
-
147
   uint8_t valcur = cb_read_byte(p);
82
   uint8_t valcur = cb_read_byte(p);
148
   if (0 == (0x80 & valcur)) {
83
   if (0 == (0x80 & valcur)) {
149
     val = valcur;
84
     val = valcur;
215
     val |= (valcur & 0x3F);
150
     val |= (valcur & 0x3F);
216
     p++;
151
     p++;
217
   }
152
   }
218
-  else if (0x80 == (0xC0 & valcur)) {
219
-    /* error? */
220
-    TRACE("ERR 1");
153
+  else if (0x80 == (0xC0 & valcur))
221
     for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
154
     for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
222
-  }
223
-  else {
224
-    /* error */
225
-    TRACE("ERR 2");
155
+  else
226
     for (; ((0xFE & valcur) > 0xFC); ) { p++; valcur = cb_read_byte(p); }
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
   if (pval) *pval = val;
158
   if (pval) *pval = val;
241
 
159
 
242
   return p;
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
     pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
169
     pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
253
-    if (pnext == NULL || ch == 0) break;
170
+    if (!ch) break;
254
     cnt++;
171
     cnt++;
255
-    TRACE("cnt=%d, ch=0x%X", cnt, (int)ch);
256
   }
172
   }
257
   return cnt;
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
 #ifndef _FONT_UTILS_H
9
 #ifndef _FONT_UTILS_H
10
 #define _FONT_UTILS_H
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
 // read a byte from ROM or RAM
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
 uint8_t read_byte_ram(uint8_t * str);
20
 uint8_t read_byte_ram(uint8_t * str);
51
 uint8_t read_byte_rom(uint8_t * str);
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
 #ifndef NUM_ARRAY
30
 #ifndef NUM_ARRAY
95
   #define NUM_ARRAY(a) (sizeof(a)/sizeof((a)[0]))
31
   #define NUM_ARRAY(a) (sizeof(a)/sizeof((a)[0]))
96
 #endif // NUM_ARRAY
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
 #define PIXEL_LEN_NOLIMIT ((pixel_len_t)(-1))
35
 #define PIXEL_LEN_NOLIMIT ((pixel_len_t)(-1))
108
 
36
 
37
+/* Perform binary search */
109
 typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin); /*"data_list[idx] - *data_pin"*/
38
 typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin); /*"data_list[idx] - *data_pin"*/
110
 int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx);
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
 uint8_t utf8_strlen(const char *pstart);
45
 uint8_t utf8_strlen(const char *pstart);
117
 uint8_t utf8_strlen_P(const char *pstart);
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
 #endif // _FONT_UTILS_H
48
 #endif // _FONT_UTILS_H

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

17
   #include "u8g_fontutf8.h"
17
   #include "u8g_fontutf8.h"
18
 #endif
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
 int lcd_glyph_height(void);
22
 int lcd_glyph_height(void);
27
 
23
 
49
  *
45
  *
50
  * Draw a ROM UTF-8 string
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
 void lcd_moveto(int col, int row);
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
 inline int lcd_put_u8str(const char* str) { return lcd_put_u8str_max(str, PIXEL_LEN_NOLIMIT); }
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
 #include "fontutils.h"
24
 #include "fontutils.h"
25
 #include "lcdprint.h"
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
 #endif
31
 #endif
32
+extern LCD_CLASS lcd;
33
+LCD_CLASS *plcd = &lcd;
41
 
34
 
42
 int lcd_glyph_height(void) { return 1; }
35
 int lcd_glyph_height(void) { return 1; }
43
 
36
 
878
 
871
 
879
 /* return v1 - v2 */
872
 /* return v1 - v2 */
880
 static int hd44780_charmap_compare(hd44780_charmap_t * v1, hd44780_charmap_t * v2) {
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
     return -1;
875
     return -1;
888
-  } else if (v1->uchar > v2->uchar) {
889
-    TRACE("compare return 1");
876
+  else if (v1->uchar > v2->uchar)
890
     return 1;
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
   return 0;
878
   return 0;
901
 }
879
 }
902
 
880
 
909
 
887
 
910
 #if DEBUG
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
   int ret;
891
   int ret;
916
   size_t idx = 0;
892
   size_t idx = 0;
917
   hd44780_charmap_t preval = {0, 0, 0};
893
   hd44780_charmap_t preval = {0, 0, 0};
963
   return 0;
939
   return 0;
964
 }
940
 }
965
 
941
 
966
-int
967
-test_hd44780_charmap_all(void)
968
-{
942
+int test_hd44780_charmap_all(void) {
969
   int flg_error = 0;
943
   int flg_error = 0;
970
   if (test_hd44780_charmap(g_hd44780_charmap_device, NUM_ARRAY(g_hd44780_charmap_device), "g_hd44780_charmap_device", 0) < 0) {
944
   if (test_hd44780_charmap(g_hd44780_charmap_device, NUM_ARRAY(g_hd44780_charmap_device), "g_hd44780_charmap_device", 0) < 0) {
971
     flg_error = 1;
945
     flg_error = 1;
986
 #endif // DEBUG
960
 #endif // DEBUG
987
 
961
 
988
 void lcd_moveto(int col, int row) {
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
 // return < 0 on error
966
 // return < 0 on error
994
 // return the advanced cols
967
 // return the advanced cols
995
 int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
968
 int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
969
+
996
   // find the HD44780 internal ROM first
970
   // find the HD44780 internal ROM first
997
   int ret;
971
   int ret;
998
   size_t idx = 0;
972
   size_t idx = 0;
999
   hd44780_charmap_t pinval;
973
   hd44780_charmap_t pinval;
1000
-  hd44780_charmap_t localval;
1001
   hd44780_charmap_t *copy_address = NULL;
974
   hd44780_charmap_t *copy_address = NULL;
1002
   pinval.uchar = c;
975
   pinval.uchar = c;
1003
   pinval.idx = -1;
976
   pinval.idx = -1;
1006
 
979
 
1007
   // TODO: fix the '\\' that doesnt exist in the HD44870
980
   // TODO: fix the '\\' that doesnt exist in the HD44870
1008
   if (c < 128) {
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
     return 1;
983
     return 1;
1012
   }
984
   }
1013
   copy_address = NULL;
985
   copy_address = NULL;
1014
   ret = pf_bsearch_r((void *)g_hd44780_charmap_device, NUM_ARRAY(g_hd44780_charmap_device), pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx);
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
   if (ret >= 0) {
987
   if (ret >= 0) {
1016
     copy_address = (hd44780_charmap_t *)(g_hd44780_charmap_device + idx);
988
     copy_address = (hd44780_charmap_t *)(g_hd44780_charmap_device + idx);
1017
-  } else {
989
+  }
990
+  else {
1018
     ret = pf_bsearch_r((void *)g_hd44780_charmap_common, NUM_ARRAY(g_hd44780_charmap_common), pf_bsearch_cb_comp_hd4map_pgm, (void *)&pinval, &idx);
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
   if (ret >= 0) {
995
   if (ret >= 0) {
996
+    hd44780_charmap_t localval;
1025
     // found
997
     // found
1026
-    FU_ASSERT(NULL != copy_address);
1027
     memcpy_P(&localval, copy_address, sizeof(localval));
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
     if (max_length >= 2 && localval.idx2 > 0) {
1000
     if (max_length >= 2 && localval.idx2 > 0) {
1032
-      _lcd_write(localval.idx2);
1001
+      plcd->write(localval.idx2);
1033
       return 2;
1002
       return 2;
1034
     }
1003
     }
1035
     return 1;
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
   return 1;
1009
   return 1;
1041
 }
1010
 }
1042
 
1011
 
1044
 * @brief Draw a UTF-8 string
1013
 * @brief Draw a UTF-8 string
1045
 *
1014
 *
1046
 * @param utf8_str : the UTF-8 string
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
 * @param cb_read_byte : the callback function to read one byte from the utf8_str (from RAM or ROM)
1016
 * @param cb_read_byte : the callback function to read one byte from the utf8_str (from RAM or ROM)
1049
 * @param max_length : the pixel length of the string allowed (or number of slots in HD44780)
1017
 * @param max_length : the pixel length of the string allowed (or number of slots in HD44780)
1050
 *
1018
 *
1052
 *
1020
 *
1053
 * Draw a UTF-8 string
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
   pixel_len_t ret = 0;
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
     p = get_utf8_value_cb(p, cb_read_byte, &ch);
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
     ret += lcd_put_wchar_max(ch, max_length - ret);
1030
     ret += lcd_put_wchar_max(ch, max_length - ret);
1071
   }
1031
   }
1072
   return (int)ret;
1032
   return (int)ret;
1073
 }
1033
 }
1074
 
1034
 
1075
 int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
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
 #endif // DOGLCD
1043
 #endif // DOGLCD

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

25
 
25
 
26
 int lcd_glyph_height(void) {
26
 int lcd_glyph_height(void) {
27
   return u8g_GetFontBBXHeight(pu8g->getU8g());
27
   return u8g_GetFontBBXHeight(pu8g->getU8g());
28
-  //return u8g_GetFontBBXOffY(pu8g->getU8g());
29
 }
28
 }
30
 
29
 
31
 void lcd_moveto(int col, int row) {
30
 void lcd_moveto(int col, int row) {
32
-  TRACE("Move to: (%d,%d)", col, row);
33
   _lcd_setcursor(col, row);
31
   _lcd_setcursor(col, row);
34
 }
32
 }
35
 
33
 
34
+// return < 0 on error
35
+// return the advanced pixels
36
 int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
36
 int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
37
   if (c < 256) {
37
   if (c < 256) {
38
-    TRACE("draw char: regular %d", (int)c);
39
     _lcd_write((char)c);
38
     _lcd_write((char)c);
40
     return u8g_GetFontBBXWidth(pu8g->getU8g());
39
     return u8g_GetFontBBXWidth(pu8g->getU8g());
41
   }
40
   }
42
   unsigned int x = pu8g->getPrintCol(),
41
   unsigned int x = pu8g->getPrintCol(),
43
                y = pu8g->getPrintRow(),
42
                y = pu8g->getPrintRow(),
44
                ret = uxg_DrawWchar(pu8g->getU8g(), x, y, c, max_length);
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
   pu8g->setPrintPos(x + ret, y);
44
   pu8g->setPrintPos(x + ret, y);
48
 
45
 
49
   return ret;
46
   return ret;
53
   unsigned int x = pu8g->getPrintCol(),
50
   unsigned int x = pu8g->getPrintCol(),
54
                y = pu8g->getPrintRow(),
51
                y = pu8g->getPrintRow(),
55
                ret = uxg_DrawUtf8Str(pu8g->getU8g(), x, y, utf8_str, max_length);
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
   pu8g->setPrintPos(x + ret, y);
53
   pu8g->setPrintPos(x + ret, y);
59
   return ret;
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
   unsigned int x = pu8g->getPrintCol(),
58
   unsigned int x = pu8g->getPrintCol(),
64
                y = pu8g->getPrintRow(),
59
                y = pu8g->getPrintRow(),
65
                ret = uxg_DrawUtf8StrP(pu8g->getU8g(), x, y, utf8_str_P, max_length);
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
   pu8g->setPrintPos(x + ret, y);
61
   pu8g->setPrintPos(x + ret, y);
69
   return ret;
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
 ////////////////////////////////////////////////////////////
18
 ////////////////////////////////////////////////////////////
19
 typedef void font_t;
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
  * @brief the callback function to draw something
22
  * @brief the callback function to draw something
45
  *
23
  *
53
  */
31
  */
54
 typedef int (* fontgroup_cb_draw_t)(void *userdata, const font_t *fnt_current, const char *msg);
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
 /* return v1 - v2 */
35
 /* return v1 - v2 */
63
 static int fontinfo_compare(uxg_fontinfo_t * v1, uxg_fontinfo_t * v2) {
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
   return 0;
43
   return 0;
77
 }
44
 }
80
 static int pf_bsearch_cb_comp_fntifo_pgm (void *userdata, size_t idx, void *data_pin) {
47
 static int pf_bsearch_cb_comp_fntifo_pgm (void *userdata, size_t idx, void *data_pin) {
81
   uxg_fontinfo_t *fntinfo = (uxg_fontinfo_t*)userdata;
48
   uxg_fontinfo_t *fntinfo = (uxg_fontinfo_t*)userdata;
82
   uxg_fontinfo_t localval;
49
   uxg_fontinfo_t localval;
83
-  memcpy_from_rom(&localval, fntinfo + idx, sizeof(localval));
50
+  memcpy_P(&localval, fntinfo + idx, sizeof(localval));
84
   return fontinfo_compare(&localval, (uxg_fontinfo_t*)data_pin);
51
   return fontinfo_compare(&localval, (uxg_fontinfo_t*)data_pin);
85
 }
52
 }
86
 
53
 
92
 static int fontgroup_init(font_group_t * root, const uxg_fontinfo_t * fntinfo, int number) {
59
 static int fontgroup_init(font_group_t * root, const uxg_fontinfo_t * fntinfo, int number) {
93
   root->m_fntifo = fntinfo;
60
   root->m_fntifo = fntinfo;
94
   root->m_fntinfo_num = number;
61
   root->m_fntinfo_num = number;
95
-
96
   return 0;
62
   return 0;
97
 }
63
 }
98
 
64
 
105
   if (pf_bsearch_r((void*)root->m_fntifo, root->m_fntinfo_num, pf_bsearch_cb_comp_fntifo_pgm, (void*)&vcmp, &idx) < 0)
71
   if (pf_bsearch_r((void*)root->m_fntifo, root->m_fntinfo_num, pf_bsearch_cb_comp_fntifo_pgm, (void*)&vcmp, &idx) < 0)
106
     return NULL;
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
   return vcmp.fntdata;
75
   return vcmp.fntdata;
110
 }
76
 }
111
 
77
 
112
 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) {
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
   uint8_t buf[2] = {0, 0};
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
     buf[0] = (uint8_t)(val & 0xFF);
83
     buf[0] = (uint8_t)(val & 0xFF);
120
     fntpqm = fnt_default;
84
     fntpqm = fnt_default;
121
-    TRACE("Unknown char %d(0x%X), use default font", (int)val, (int)val);
122
   }
85
   }
123
   if (fnt_default != fntpqm) {
86
   if (fnt_default != fntpqm) {
124
     buf[0] = (uint8_t)(val & 0x7F);
87
     buf[0] = (uint8_t)(val & 0x7F);
125
     buf[0] |= 0x80; // use upper page to avoid 0x00 error in C. you may want to generate the font data
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
   cb_draw_ram (userdata, fntpqm, (char*) buf);
91
   cb_draw_ram (userdata, fntpqm, (char*) buf);
129
 }
92
 }
130
 
93
 
142
  *
105
  *
143
  * Get the screen pixel width of a ROM UTF-8 string
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
     wchar_t val = 0;
111
     wchar_t val = 0;
149
     p = get_utf8_value_cb(p, cb_read_byte, &val);
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
     fontgroup_drawwchar(group, fnt_default, val, userdata, cb_draw_ram);
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
 static font_group_t g_fontgroup_root = {NULL, 0};
120
 static font_group_t g_fontgroup_root = {NULL, 0};
162
 
121
 
163
 /**
122
 /**
164
  * @brief check if font is loaded
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
 int uxg_SetUtf8Fonts (const uxg_fontinfo_t * fntinfo, int number) {
127
 int uxg_SetUtf8Fonts (const uxg_fontinfo_t * fntinfo, int number) {
169
-  flag_fontgroup_inited = 1;
128
+  flag_fontgroup_was_inited = 1;
170
   return fontgroup_init(&g_fontgroup_root, fntinfo, number);
129
   return fontgroup_init(&g_fontgroup_root, fntinfo, number);
171
 }
130
 }
172
 
131
 
179
   const void * fnt_prev;
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
   struct _uxg_drawu8_data_t * pdata = (_uxg_drawu8_data_t*)userdata;
142
   struct _uxg_drawu8_data_t * pdata = (_uxg_drawu8_data_t*)userdata;
184
 
143
 
185
-  FU_ASSERT(NULL != userdata);
186
   if (pdata->fnt_prev != fnt_current) {
144
   if (pdata->fnt_prev != fnt_current) {
187
     u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current);
145
     u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current);
188
     //u8g_SetFontPosBottom(pdata->pu8g);
146
     //u8g_SetFontPosBottom(pdata->pu8g);
189
     pdata->fnt_prev = fnt_current;
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
     return 1;
150
     return 1;
194
-  }
195
-  TRACE("Draw string 0x%X", (int)msg[0]);
196
   pdata->adv += u8g_DrawStr(pdata->pu8g, pdata->x + pdata->adv, pdata->y, (char*) msg);
151
   pdata->adv += u8g_DrawStr(pdata->pu8g, pdata->x + pdata->adv, pdata->y, (char*) msg);
197
-  //TRACE("adv pos= %d", pdata->adv);
198
   return 0;
152
   return 0;
199
 }
153
 }
200
 
154
 
260
   data.adv = 0;
214
   data.adv = 0;
261
   data.max_width = max_width;
215
   data.max_width = max_width;
262
   data.fnt_prev = NULL;
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
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
218
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
265
 
219
 
266
   return data.adv;
220
   return data.adv;
285
   const font_t *fnt_default = uxg_GetFont(pu8g);
239
   const font_t *fnt_default = uxg_GetFont(pu8g);
286
 
240
 
287
   if (!uxg_Utf8FontIsInited()) {
241
   if (!uxg_Utf8FontIsInited()) {
288
-    TRACE("Error, utf8string not inited!");
289
     u8g_DrawStrP(pu8g, x, y, (const u8g_pgm_uint8_t *)PSTR("Err: utf8 font not initialized."));
242
     u8g_DrawStrP(pu8g, x, y, (const u8g_pgm_uint8_t *)PSTR("Err: utf8 font not initialized."));
290
     return 0;
243
     return 0;
291
   }
244
   }
295
   data.adv = 0;
248
   data.adv = 0;
296
   data.max_width = max_width;
249
   data.max_width = max_width;
297
   data.fnt_prev = NULL;
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
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
252
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
302
 
253
 
303
-  TRACE("return %d", data.adv);
304
   return data.adv;
254
   return data.adv;
305
 }
255
 }
306
 
256
 
307
 static int fontgroup_cb_draw_u8gstrlen(void *userdata, const font_t *fnt_current, const char *msg) {
257
 static int fontgroup_cb_draw_u8gstrlen(void *userdata, const font_t *fnt_current, const char *msg) {
308
   struct _uxg_drawu8_data_t * pdata = (_uxg_drawu8_data_t*)userdata;
258
   struct _uxg_drawu8_data_t * pdata = (_uxg_drawu8_data_t*)userdata;
309
 
259
 
310
-  FU_ASSERT(NULL != userdata);
311
   if (pdata->fnt_prev != fnt_current) {
260
   if (pdata->fnt_prev != fnt_current) {
312
     u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current);
261
     u8g_SetFont(pdata->pu8g, (const u8g_fntpgm_uint8_t*)fnt_current);
313
     u8g_SetFontPosBottom(pdata->pu8g);
262
     u8g_SetFontPosBottom(pdata->pu8g);
332
   font_group_t *group = &g_fontgroup_root;
281
   font_group_t *group = &g_fontgroup_root;
333
   const font_t *fnt_default = uxg_GetFont(pu8g);
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
   memset(&data, 0, sizeof(data));
286
   memset(&data, 0, sizeof(data));
341
   data.pu8g = pu8g;
287
   data.pu8g = pu8g;
342
   data.adv = 0;
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
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
290
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
345
 
291
 
346
   return data.adv;
292
   return data.adv;
361
   font_group_t *group = &g_fontgroup_root;
307
   font_group_t *group = &g_fontgroup_root;
362
   const font_t *fnt_default = uxg_GetFont(pu8g);
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
   memset(&data, 0, sizeof(data));
312
   memset(&data, 0, sizeof(data));
369
   data.pu8g = pu8g;
313
   data.pu8g = pu8g;
370
   data.adv = 0;
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
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
316
   u8g_SetFont(pu8g, (const u8g_fntpgm_uint8_t*)fnt_default);
373
   return data.adv;
317
   return data.adv;
374
 }
318
 }

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

12
 #include <U8glib.h>
12
 #include <U8glib.h>
13
 #include "fontutils.h"
13
 #include "fontutils.h"
14
 
14
 
15
-#ifdef __cplusplus
16
-extern "C" {
17
-#endif
18
-
19
-
20
 // the macro to indicate a UTF-8 string
15
 // the macro to indicate a UTF-8 string
21
 // You should to save the C/C++ source in UTF-8 encoding!
16
 // You should to save the C/C++ source in UTF-8 encoding!
22
 // Once you change your UTF-8 strings, you need to call the script uxggenpages.sh to create the font data file fontutf8-data.h
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
     const u8g_fntpgm_uint8_t *fntdata;
25
     const u8g_fntpgm_uint8_t *fntdata;
31
 } uxg_fontinfo_t;
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
 #define uxg_GetFont(puxg) ((puxg)->font)
38
 #define uxg_GetFont(puxg) ((puxg)->font)
45
 
39
 
46
-#ifdef __cplusplus
47
-}
48
-#endif
49
-
50
 #endif // _UXG_FONTUTF8_H
40
 #endif // _UXG_FONTUTF8_H

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

80
   #else
80
   #else
81
     #define MAX_MESSAGE_LENGTH CHARSIZE * 2 * (LCD_WIDTH)
81
     #define MAX_MESSAGE_LENGTH CHARSIZE * 2 * (LCD_WIDTH)
82
   #endif
82
   #endif
83
-  uint8_t status_scroll_pos = 0;
83
+  uint8_t status_scroll_offset = 0;
84
 #else
84
 #else
85
   #define MAX_MESSAGE_LENGTH CHARSIZE * (LCD_WIDTH)
85
   #define MAX_MESSAGE_LENGTH CHARSIZE * (LCD_WIDTH)
86
 #endif
86
 #endif
5360
   } // ELAPSED(ms, next_lcd_update_ms)
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
 void lcd_finishstatus(const bool persist=false) {
5363
 void lcd_finishstatus(const bool persist=false) {
5384
 
5364
 
5385
-  pad_message_string();
5386
-
5387
   #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
5365
   #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
5388
     UNUSED(persist);
5366
     UNUSED(persist);
5389
   #endif
5367
   #endif
5401
   #endif
5379
   #endif
5402
 
5380
 
5403
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
5381
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
5404
-    status_scroll_pos = 0;
5382
+    status_scroll_offset = 0;
5405
   #endif
5383
   #endif
5406
 }
5384
 }
5407
 
5385
 
5413
 
5391
 
5414
 void lcd_setstatus(const char * const message, const bool persist) {
5392
 void lcd_setstatus(const char * const message, const bool persist) {
5415
   if (lcd_status_message_level > 0) return;
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
   lcd_finishstatus(persist);
5414
   lcd_finishstatus(persist);
5418
 }
5415
 }
5419
 
5416
 
5421
   if (level < 0) level = lcd_status_message_level = 0;
5418
   if (level < 0) level = lcd_status_message_level = 0;
5422
   if (level < lcd_status_message_level) return;
5419
   if (level < lcd_status_message_level) return;
5423
   lcd_status_message_level = level;
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
   lcd_finishstatus(level > 0);
5441
   lcd_finishstatus(level > 0);
5426
 }
5442
 }
5427
 
5443
 

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

341
     lcd_moveto(0, h4 * 1);
341
     lcd_moveto(0, h4 * 1);
342
     lcd_put_u8str(lcd_status_message);
342
     lcd_put_u8str(lcd_status_message);
343
     lcd_moveto(0, h4 * 2);
343
     lcd_moveto(0, h4 * 2);
344
-    lcd_put_u8str_rom(PSTR(MSG_HALTED));
344
+    lcd_put_u8str_P(PSTR(MSG_HALTED));
345
     lcd_moveto(0, h4 * 3);
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
   } while (u8g.nextPage());
347
   } while (u8g.nextPage());
348
 }
348
 }
349
 
349
 
415
         int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
415
         int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
416
         while (--pad >= 0) { lcd_put_wchar(' '); n--; }
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
       if (NULL != valstr) {
419
       if (NULL != valstr) {
420
         n -= lcd_put_u8str_max(valstr, n);
420
         n -= lcd_put_u8str_max(valstr, n);
421
       }
421
       }
431
     if (lcd_implementation_mark_as_selected(row, isSelected)) {
431
     if (lcd_implementation_mark_as_selected(row, isSelected)) {
432
       uint8_t n = LCD_WIDTH - (START_COL) - 2;
432
       uint8_t n = LCD_WIDTH - (START_COL) - 2;
433
       n *= DOG_CHAR_WIDTH;
433
       n *= DOG_CHAR_WIDTH;
434
-      n -= lcd_put_u8str_max_rom(pstr, n);
434
+      n -= lcd_put_u8str_max_P(pstr, n);
435
       while (n - DOG_CHAR_WIDTH > 0) { n -= lcd_put_wchar(' '); }
435
       while (n - DOG_CHAR_WIDTH > 0) { n -= lcd_put_wchar(' '); }
436
       lcd_moveto(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), row_y2);
436
       lcd_moveto(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), row_y2);
437
       lcd_put_wchar(post_char);
437
       lcd_put_wchar(post_char);
451
       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
451
       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data));
452
       uint8_t n = LCD_WIDTH - (START_COL) - 2 - vallen;
452
       uint8_t n = LCD_WIDTH - (START_COL) - 2 - vallen;
453
       n *= DOG_CHAR_WIDTH;
453
       n *= DOG_CHAR_WIDTH;
454
-      n -= lcd_put_u8str_max_rom(pstr, n);
454
+      n -= lcd_put_u8str_max_P(pstr, n);
455
       lcd_put_wchar(':');
455
       lcd_put_wchar(':');
456
       while (n - DOG_CHAR_WIDTH > 0) { n -= lcd_put_wchar(' '); }
456
       while (n - DOG_CHAR_WIDTH > 0) { n -= lcd_put_wchar(' '); }
457
       lcd_moveto(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH) * vallen, row_y2);
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
     bool onpage = PAGE_CONTAINS(baseline + 1 - (DOG_CHAR_HEIGHT_EDIT), baseline);
499
     bool onpage = PAGE_CONTAINS(baseline + 1 - (DOG_CHAR_HEIGHT_EDIT), baseline);
500
     if (onpage) {
500
     if (onpage) {
501
       lcd_moveto(0, baseline);
501
       lcd_moveto(0, baseline);
502
-      lcd_put_u8str_rom(pstr);
502
+      lcd_put_u8str_P(pstr);
503
     }
503
     }
504
 
504
 
505
     if (value != NULL) {
505
     if (value != NULL) {
641
         if (!isnan(ubl.z_values[x_plot][y_plot]))
641
         if (!isnan(ubl.z_values[x_plot][y_plot]))
642
           lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot]));
642
           lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot]));
643
         else
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
   }
347
   }
348
 
348
 
349
   // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line
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
         lcd_moveto(col, line);
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
   static void logo_lines(const char* const extra) {
390
   static void logo_lines(const char* const extra) {
366
     int16_t indent = (LCD_WIDTH - 8 - utf8_strlen_P(extra)) / 2;
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
   void lcd_bootscreen() {
397
   void lcd_bootscreen() {
379
       lcd_erase_line(3); \
404
       lcd_erase_line(3); \
380
       if (utf8_strlen(STRING) <= LCD_WIDTH) { \
405
       if (utf8_strlen(STRING) <= LCD_WIDTH) { \
381
         lcd_moveto((LCD_WIDTH - utf8_strlen_P(PSTR(STRING))) / 2, 3); \
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
         safe_delay(DELAY); \
408
         safe_delay(DELAY); \
384
       } \
409
       } \
385
       else { \
410
       else { \
452
     lcd_moveto(0, 2);
477
     lcd_moveto(0, 2);
453
   #else
478
   #else
454
     lcd_moveto(0, 2);
479
     lcd_moveto(0, 2);
455
-    lcd_put_u8str_rom(PSTR(MSG_HALTED));
480
+    lcd_put_u8str_P(PSTR(MSG_HALTED));
456
     lcd_moveto(0, 3);
481
     lcd_moveto(0, 3);
457
   #endif
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
     else {
498
     else {
474
       #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
499
       #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
475
         if (!axis_known_position[axis])
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
         else
502
         else
478
       #endif
503
       #endif
479
           lcd_put_u8str(value);
504
           lcd_put_u8str(value);
634
 
659
 
635
       #if ENABLED(SDSUPPORT)
660
       #if ENABLED(SDSUPPORT)
636
         lcd_moveto(0, 2);
661
         lcd_moveto(0, 2);
637
-        lcd_put_u8str_rom(PSTR("SD"));
662
+        lcd_put_u8str_P(PSTR("SD"));
638
         if (IS_SD_PRINTING)
663
         if (IS_SD_PRINTING)
639
           lcd_put_u8str(itostr3(card.percentDone()));
664
           lcd_put_u8str(itostr3(card.percentDone()));
640
         else
665
         else
641
-          lcd_put_u8str_rom(PSTR("---"));
666
+          lcd_put_u8str_P(PSTR("---"));
642
           lcd_put_wchar('%');
667
           lcd_put_wchar('%');
643
       #endif // SDSUPPORT
668
       #endif // SDSUPPORT
644
 
669
 
698
     #if LCD_WIDTH >= 20 && ENABLED(SDSUPPORT)
723
     #if LCD_WIDTH >= 20 && ENABLED(SDSUPPORT)
699
 
724
 
700
       lcd_moveto(7, 2);
725
       lcd_moveto(7, 2);
701
-      lcd_put_u8str_rom(PSTR("SD"));
726
+      lcd_put_u8str_P(PSTR("SD"));
702
       if (IS_SD_PRINTING)
727
       if (IS_SD_PRINTING)
703
         lcd_put_u8str(itostr3(card.percentDone()));
728
         lcd_put_u8str(itostr3(card.percentDone()));
704
       else
729
       else
705
-        lcd_put_u8str_rom(PSTR("---"));
730
+        lcd_put_u8str_P(PSTR("---"));
706
       lcd_put_wchar('%');
731
       lcd_put_wchar('%');
707
 
732
 
708
     #endif // LCD_WIDTH >= 20 && SDSUPPORT
733
     #endif // LCD_WIDTH >= 20 && SDSUPPORT
739
     // Show Filament Diameter and Volumetric Multiplier %
764
     // Show Filament Diameter and Volumetric Multiplier %
740
     // After allowing lcd_status_message to show for 5 seconds
765
     // After allowing lcd_status_message to show for 5 seconds
741
     if (ELAPSED(millis(), previous_lcd_status_ms + 5000UL)) {
766
     if (ELAPSED(millis(), previous_lcd_status_ms + 5000UL)) {
742
-      lcd_put_u8str_rom(PSTR("Dia "));
767
+      lcd_put_u8str_P(PSTR("Dia "));
743
       lcd_put_u8str(ftostr12ns(filament_width_meas));
768
       lcd_put_u8str(ftostr12ns(filament_width_meas));
744
-      lcd_put_u8str_rom(PSTR(" V"));
769
+      lcd_put_u8str_P(PSTR(" V"));
745
       lcd_put_u8str(itostr3(100.0 * (
770
       lcd_put_u8str(itostr3(100.0 * (
746
           parser.volumetric_enabled
771
           parser.volumetric_enabled
747
             ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
772
             ? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
756
 
781
 
757
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
782
   #if ENABLED(STATUS_MESSAGE_SCROLLING)
758
     static bool last_blink = false;
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
     else {
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
       else {
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
       if (last_blink != blink) {
827
       if (last_blink != blink) {
780
         last_blink = blink;
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
   #else
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
   #endif
854
   #endif
789
 }
855
 }
790
 
856
 
809
       int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
875
       int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
810
       while (--pad >= 0) { lcd_put_wchar(' '); n--; }
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
     if (valstr) n -= lcd_put_u8str_max(valstr, n);
879
     if (valstr) n -= lcd_put_u8str_max(valstr, n);
814
     for (; n > 0; --n) lcd_put_wchar(' ');
880
     for (; n > 0; --n) lcd_put_wchar(' ');
815
   }
881
   }
818
     uint8_t n = LCD_WIDTH - 2;
884
     uint8_t n = LCD_WIDTH - 2;
819
     lcd_moveto(0, row);
885
     lcd_moveto(0, row);
820
     lcd_put_wchar(sel ? pre_char : ' ');
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
     while (n--) lcd_put_wchar(' ');
888
     while (n--) lcd_put_wchar(' ');
823
     lcd_put_wchar(post_char);
889
     lcd_put_wchar(post_char);
824
   }
890
   }
827
     uint8_t n = LCD_WIDTH - 2 - utf8_strlen(data);
893
     uint8_t n = LCD_WIDTH - 2 - utf8_strlen(data);
828
     lcd_moveto(0, row);
894
     lcd_moveto(0, row);
829
     lcd_put_wchar(sel ? pre_char : ' ');
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
     lcd_put_wchar(':');
897
     lcd_put_wchar(':');
832
     while (n--) lcd_put_wchar(' ');
898
     while (n--) lcd_put_wchar(' ');
833
     lcd_put_u8str(data);
899
     lcd_put_u8str(data);
836
     uint8_t n = LCD_WIDTH - 2 - utf8_strlen_P(data);
902
     uint8_t n = LCD_WIDTH - 2 - utf8_strlen_P(data);
837
     lcd_moveto(0, row);
903
     lcd_moveto(0, row);
838
     lcd_put_wchar(sel ? pre_char : ' ');
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
     lcd_put_wchar(':');
906
     lcd_put_wchar(':');
841
     while (n--) lcd_put_wchar(' ');
907
     while (n--) lcd_put_wchar(' ');
842
-    lcd_put_u8str_rom(data);
908
+    lcd_put_u8str_P(data);
843
   }
909
   }
844
 
910
 
845
   #define DRAWMENU_SETTING_EDIT_GENERIC(_src) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', _src)
911
   #define DRAWMENU_SETTING_EDIT_GENERIC(_src) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', _src)
847
 
913
 
848
   void lcd_implementation_drawedit(const char* pstr, const char* const value=NULL) {
914
   void lcd_implementation_drawedit(const char* pstr, const char* const value=NULL) {
849
     lcd_moveto(1, 1);
915
     lcd_moveto(1, 1);
850
-    lcd_put_u8str_rom(pstr);
916
+    lcd_put_u8str_P(pstr);
851
     if (value != NULL) {
917
     if (value != NULL) {
852
       lcd_put_wchar(':');
918
       lcd_put_wchar(':');
853
       int len = utf8_strlen(value);
919
       int len = utf8_strlen(value);
1293
         if (!isnan(ubl.z_values[x][inverted_y]))
1359
         if (!isnan(ubl.z_values[x][inverted_y]))
1294
           lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1360
           lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1295
         else
1361
         else
1296
-          lcd_put_u8str_rom(PSTR(" -----"));
1362
+          lcd_put_u8str_P(PSTR(" -----"));
1297
 
1363
 
1298
       #else                 // 16x4 or 20x4 display
1364
       #else                 // 16x4 or 20x4 display
1299
 
1365
 
1312
         if (!isnan(ubl.z_values[x][inverted_y]))
1378
         if (!isnan(ubl.z_values[x][inverted_y]))
1313
           lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1379
           lcd_put_u8str(ftostr43sign(ubl.z_values[x][inverted_y]));
1314
         else
1380
         else
1315
-          lcd_put_u8str_rom(PSTR(" -----"));
1381
+          lcd_put_u8str_P(PSTR(" -----"));
1316
 
1382
 
1317
       #endif // LCD_HEIGHT > 3
1383
       #endif // LCD_HEIGHT > 3
1318
     }
1384
     }

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

563
   uint32_t ptr, val;
563
   uint32_t ptr, val;
564
 
564
 
565
   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
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
   val = *((uint32_t *)(ptr + 3*4));            /* Status Information */
568
   val = *((uint32_t *)(ptr + 3*4));            /* Status Information */
570
   switch ((val >> 1) & 0x0F) {
569
   switch ((val >> 1) & 0x0F) {
596
 
595
 
597
 uint32_t USB_DMA_BufAdr (uint32_t EPNum) {
596
 uint32_t USB_DMA_BufAdr (uint32_t EPNum) {
598
   uint32_t ptr, val;
597
   uint32_t ptr, val;
599
-
600
   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
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
   val = *((uint32_t *)(ptr + 2*4));         /* Buffer Address */
600
   val = *((uint32_t *)(ptr + 2*4));         /* Buffer Address */
607
   return (val);                             /* Current Address */
601
   return (val);                             /* Current Address */
608
 }
602
 }
619
 
613
 
620
 uint32_t USB_DMA_BufCnt (uint32_t EPNum) {
614
 uint32_t USB_DMA_BufCnt (uint32_t EPNum) {
621
   uint32_t ptr, val;
615
   uint32_t ptr, val;
622
-
623
   ptr = UDCA[EPAdr(EPNum)];                 /* Current Descriptor */
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
   val = *((uint32_t *)(ptr + 3*4));         /* Status Information */
618
   val = *((uint32_t *)(ptr + 3*4));         /* Status Information */
629
   return (val >> 16);                       /* Current Count */
619
   return (val >> 16);                       /* Current Count */
630
 }
620
 }
695
 #if USB_SOF_EVENT
685
 #if USB_SOF_EVENT
696
   /* Start of Frame Interrupt */
686
   /* Start of Frame Interrupt */
697
   if (disr & FRAME_INT) {
687
   if (disr & FRAME_INT) {
698
-	LPC_USB->USBDevIntClr = FRAME_INT;
688
+    LPC_USB->USBDevIntClr = FRAME_INT;
699
     USB_SOF_Event();
689
     USB_SOF_Event();
700
   }
690
   }
701
 #endif
691
 #endif
703
 #if USB_ERROR_EVENT
693
 #if USB_ERROR_EVENT
704
   /* Error Interrupt */
694
   /* Error Interrupt */
705
   if (disr & ERR_INT) {
695
   if (disr & ERR_INT) {
706
-	LPC_USB->USBDevIntClr = ERR_INT;
696
+    LPC_USB->USBDevIntClr = ERR_INT;
707
     WrCmd(CMD_RD_ERR_STAT);
697
     WrCmd(CMD_RD_ERR_STAT);
708
     val = RdCmdDat(DAT_RD_ERR_STAT);
698
     val = RdCmdDat(DAT_RD_ERR_STAT);
709
     USB_Error_Event(val);
699
     USB_Error_Event(val);

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