My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /**
  2. * @file fontutils.cpp
  3. * @brief help functions for font and char
  4. * @author Yunhui Fu (yhfudev@gmail.com)
  5. * @version 1.0
  6. * @date 2016-08-19
  7. * @copyright GPL/BSD
  8. */
  9. #include "../inc/MarlinConfig.h"
  10. #if ENABLED(ULTRA_LCD)
  11. #include "ultralcd.h"
  12. #include "../Marlin.h"
  13. #endif
  14. #include "fontutils.h"
  15. uint8_t read_byte_ram(uint8_t * str) { return *str; }
  16. uint8_t read_byte_rom(uint8_t * str) { return pgm_read_byte(str); }
  17. #if DEBUG
  18. #ifdef ARDUINO
  19. #include <Arduino.h>
  20. #include <stdarg.h>
  21. void serial_printf_P(const char *format, ...) {
  22. static char buff[128];
  23. va_list args;
  24. va_start(args,format);
  25. vsnprintf_P(buff,sizeof(buff),format,args);
  26. va_end(args);
  27. buff[sizeof(buff)/sizeof(buff[0])-1]='\0';
  28. //Serial.print(buff);
  29. SERIAL_ECHO(buff); SERIAL_EOL;
  30. }
  31. #endif
  32. #endif
  33. #ifdef __WIN32__ // or whatever
  34. #define PRIiSZ "ld"
  35. #define PRIuSZ "Iu"
  36. #else
  37. #define PRIiSZ "zd"
  38. #define PRIuSZ "zu"
  39. #endif
  40. #define PRIiOFF "lld"
  41. #define PRIuOFF "llu"
  42. #define DBGMSG(a,b, ...) TRACE( #__VA_ARGS__ )
  43. //typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin); /*"data_list[idx] - *data_pin"*/
  44. /**
  45. * @brief 折半方式查找记录
  46. *
  47. * @param userdata : 用户数据指针
  48. * @param num_data : 数据个数
  49. * @param cb_comp : 比较两个数据的回调函数
  50. * @param data_pinpoint : 所要查找的 匹配数据指针
  51. * @param ret_idx : 查找到的位置;如果没有找到,则返回如添加该记录时其所在的位置。
  52. *
  53. * @return 找到则返回0,否则返回<0
  54. *
  55. * 折半方式查找记录, psl->marr 中指向的数据已经以先小后大方式排好序
  56. */
  57. /**
  58. * @brief Using binary search to find the position by data_pin
  59. *
  60. * @param userdata : User's data
  61. * @param num_data : the item number of the sorted data
  62. * @param cb_comp : the callback function to compare the user's data and pin
  63. * @param data_pin : The reference data to be found
  64. * @param ret_idx : the position of the required data; If failed, then it is the failed position, which is the insert position if possible.
  65. *
  66. * @return 0 on found, <0 on failed(fail position is saved by ret_idx)
  67. *
  68. * Using binary search to find the position by data_pin. The user's data should be sorted.
  69. */
  70. int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx) {
  71. int retcomp;
  72. FU_ASSERT(NULL != ret_idx);
  73. /* 查找合适的位置 */
  74. if (num_data < 1) {
  75. *ret_idx = 0;
  76. DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_ERROR, "num_data(%" PRIuSZ ") < 1", num_data);
  77. return -1;
  78. }
  79. /* 折半查找 */
  80. /* 为了不出现负数,以免缩小索引的所表示的数据范围
  81. * (负数表明减少一位二进制位的使用),
  82. * 内部 ileft 和 iright使用从1开始的下标,
  83. * 即1表示C语言中的0, 2表示语言中的1,以此类推。
  84. * 对外还是使用以 0 为开始的下标
  85. */
  86. size_t i = 0, ileft = 1, iright = num_data;
  87. bool flg_found = false;
  88. for (; ileft <= iright;) {
  89. i = (ileft + iright) / 2 - 1;
  90. /* cb_comp should return the *userdata[i] - *data_pinpoint */
  91. retcomp = cb_comp (userdata, i, data_pinpoint);
  92. if (retcomp > 0)
  93. iright = i;
  94. else if (retcomp < 0)
  95. ileft = i + 2;
  96. else {
  97. /* found ! */
  98. flg_found = true;
  99. break;
  100. }
  101. }
  102. if (flg_found) {
  103. *ret_idx = i;
  104. return 0;
  105. }
  106. if (iright <= i)
  107. *ret_idx = i;
  108. else if (ileft >= i + 2)
  109. *ret_idx = i + 1;
  110. //DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_DEBUG, "not found! num_data=%" PRIuSZ "; ileft=%" PRIuSZ ", iright=%" PRIuSZ ", i=%" PRIuSZ "", num_data, ileft, iright, i);
  111. return -1;
  112. }
  113. /**
  114. * @brief 转换 UTF-8 编码的一个字符为本地的 Unicode 字符(wchar_t)
  115. *
  116. * @param pstart : 存储 UTF-8 字符的指针
  117. * @param cb_read_byte : 读取字符的函数;用于8位MCU ROM
  118. * @param pval : 需要返回的 Unicode 字符存放地址指针
  119. *
  120. * @return 成功返回下个 UTF-8 字符的位置
  121. *
  122. * 转换 UTF-8 编码的一个字符为本地的 Unicode 字符(wchar_t)
  123. */
  124. uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
  125. uint32_t val = 0;
  126. uint8_t *p = pstart;
  127. FU_ASSERT(NULL != pstart);
  128. FU_ASSERT(NULL != cb_read_byte);
  129. uint8_t valcur = cb_read_byte(p);
  130. if (0 == (0x80 & valcur)) {
  131. val = valcur;
  132. p++;
  133. }
  134. else if (0xC0 == (0xE0 & valcur)) {
  135. val = valcur & 0x1F;
  136. val <<= 6;
  137. p++;
  138. valcur = cb_read_byte(p);
  139. val |= (valcur & 0x3F);
  140. p++;
  141. }
  142. else if (0xE0 == (0xF0 & valcur)) {
  143. val = valcur & 0x0F;
  144. val <<= 6; p++;
  145. valcur = cb_read_byte(p);
  146. val |= (valcur & 0x3F);
  147. val <<= 6; p++;
  148. valcur = cb_read_byte(p);
  149. val |= (valcur & 0x3F);
  150. p++;
  151. }
  152. else if (0xF0 == (0xF8 & valcur)) {
  153. val = valcur & 0x07;
  154. val <<= 6; p++;
  155. valcur = cb_read_byte(p);
  156. val |= (valcur & 0x3F);
  157. val <<= 6; p++;
  158. valcur = cb_read_byte(p);
  159. val |= (valcur & 0x3F);
  160. val <<= 6; p++;
  161. valcur = cb_read_byte(p);
  162. val |= (valcur & 0x3F);
  163. p++;
  164. }
  165. else if (0xF8 == (0xFC & valcur)) {
  166. val = valcur & 0x03;
  167. val <<= 6; p++;
  168. valcur = cb_read_byte(p);
  169. val |= (valcur & 0x3F);
  170. val <<= 6; p++;
  171. valcur = cb_read_byte(p);
  172. val |= (valcur & 0x3F);
  173. val <<= 6; p++;
  174. valcur = cb_read_byte(p);
  175. val |= (valcur & 0x3F);
  176. val <<= 6; p++;
  177. valcur = cb_read_byte(p);
  178. val |= (valcur & 0x3F);
  179. p++;
  180. }
  181. else if (0xFC == (0xFE & valcur)) {
  182. val = valcur & 0x01;
  183. val <<= 6; p++;
  184. valcur = cb_read_byte(p);
  185. val |= (valcur & 0x3F);
  186. val <<= 6; p++;
  187. valcur = cb_read_byte(p);
  188. val |= (valcur & 0x3F);
  189. val <<= 6; p++;
  190. valcur = cb_read_byte(p);
  191. val |= (valcur & 0x3F);
  192. val <<= 6; p++;
  193. valcur = cb_read_byte(p);
  194. val |= (valcur & 0x3F);
  195. val <<= 6; p++;
  196. valcur = cb_read_byte(p);
  197. val |= (valcur & 0x3F);
  198. p++;
  199. }
  200. else if (0x80 == (0xC0 & valcur)) {
  201. /* error? */
  202. TRACE("ERR 1");
  203. for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
  204. }
  205. else {
  206. /* error */
  207. TRACE("ERR 2");
  208. for (; ((0xFE & valcur) > 0xFC); ) { p++; valcur = cb_read_byte(p); }
  209. }
  210. /*
  211. if (val == 0) {
  212. p = NULL;
  213. */
  214. /*
  215. }
  216. else if (pstart + maxlen < p) {
  217. p = pstart;
  218. if (pval) *pval = 0;
  219. }
  220. */
  221. if (pval) *pval = val;
  222. return p;
  223. }
  224. // uint8_t * get_utf8_value_cb (uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
  225. int utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
  226. wchar_t ch;
  227. uint8_t *pnext;
  228. int cnt = 0;
  229. for (pnext = (uint8_t *)pstart; ; ) {
  230. pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
  231. if (pnext == NULL || ch == 0) break;
  232. cnt++;
  233. TRACE("cnt=%d, ch=0x%X", cnt, (int)ch);
  234. }
  235. return cnt;
  236. }
  237. int
  238. my_strlen_P(const char *pstart)
  239. {
  240. const char *p;
  241. FU_ASSERT(NULL != pstart);
  242. p = pstart;
  243. while (p && pgm_read_byte(p) != '\0') p ++;
  244. return (p - pstart);
  245. }
  246. uint8_t utf8_strlen(const char *pstart) { return utf8_strlen_cb(pstart, read_byte_ram); }
  247. uint8_t utf8_strlen_P(const char *pstart) { return utf8_strlen_cb(pstart, read_byte_rom); }
  248. char* utf8_strncpy_cb( char * destination, const char *source, size_t num, int len_src, read_byte_cb_t cb_read_byte) {
  249. uint8_t *p = (uint8_t *)source;
  250. uint8_t *d = (uint8_t *)destination;
  251. FU_ASSERT(NULL != destination);
  252. FU_ASSERT(NULL != source);
  253. FU_ASSERT(NULL != cb_read_byte);
  254. uint8_t *pend = p + len_src;
  255. while (p < pend) {
  256. uint8_t valcur = cb_read_byte(p);
  257. size_t len = 0;
  258. if (0 == (0x80 & valcur))
  259. len = 1;
  260. else if (0xC0 == (0xE0 & valcur))
  261. len = 2;
  262. else if (0xE0 == (0xF0 & valcur))
  263. len = 3;
  264. else if (0xF0 == (0xF8 & valcur))
  265. len = 4;
  266. else if (0xF8 == (0xFC & valcur))
  267. len = 5;
  268. else if (0xFC == (0xFE & valcur))
  269. len = 6;
  270. else if (0x80 == (0xC0 & valcur)) {
  271. /* error? */
  272. for (; 0x80 == (0xC0 & valcur) && (p < pend); ) { p++; valcur = cb_read_byte(p); }
  273. }
  274. else {
  275. /* error */
  276. for (; ((0xFE & valcur) > 0xFC) && (p < pend); ) { p++; valcur = cb_read_byte(p); }
  277. }
  278. if (len < num) {
  279. for (size_t i = 0; i < len; i++) {
  280. valcur = cb_read_byte(p);
  281. *d = valcur;
  282. d++;
  283. p++;
  284. }
  285. }
  286. else
  287. break;
  288. }
  289. *d = 0;
  290. return destination;
  291. }
  292. char* utf8_strncpy(char * destination, const char * source, size_t num) {
  293. return utf8_strncpy_cb(destination, source, num, strlen(source), read_byte_ram);
  294. }
  295. char* utf8_strncpy_P(char * destination, const char * source, size_t num) {
  296. return utf8_strncpy_cb(destination, source, num, my_strlen_P(source), read_byte_rom);
  297. }