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.

fontutils.cpp 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 HAS_SPI_LCD
  11. #include "ultralcd.h"
  12. #include "../MarlinCore.h"
  13. #endif
  14. #include "fontutils.h"
  15. uint8_t read_byte_ram(uint8_t * str) {
  16. return *str;
  17. }
  18. uint8_t read_byte_rom(uint8_t * str) {
  19. return pgm_read_byte(str);
  20. }
  21. /**
  22. * @brief Using binary search to find the position by data_pin
  23. *
  24. * @param userdata : User's data
  25. * @param num_data : the item number of the sorted data
  26. * @param cb_comp : the callback function to compare the user's data and pin
  27. * @param data_pin : The reference data to be found
  28. * @param ret_idx : the position of the required data; If failed, then it is the failed position, which is the insert position if possible.
  29. *
  30. * @return 0 on found, <0 on failed(fail position is saved by ret_idx)
  31. *
  32. * Using binary search to find the position by data_pin. The user's data should be sorted.
  33. */
  34. int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx) {
  35. int retcomp;
  36. if (num_data < 1) {
  37. *ret_idx = 0;
  38. return -1;
  39. }
  40. size_t i = 0, ileft = 1, iright = num_data;
  41. bool flg_found = false;
  42. for (; ileft <= iright;) {
  43. i = (ileft + iright) / 2 - 1;
  44. /* cb_comp should return the *userdata[i] - *data_pinpoint */
  45. retcomp = cb_comp (userdata, i, data_pinpoint);
  46. if (retcomp > 0)
  47. iright = i;
  48. else if (retcomp < 0)
  49. ileft = i + 2;
  50. else {
  51. /* found ! */
  52. flg_found = true;
  53. break;
  54. }
  55. }
  56. if (flg_found) {
  57. *ret_idx = i;
  58. return 0;
  59. }
  60. if (iright <= i)
  61. *ret_idx = i;
  62. else if (ileft >= i + 2)
  63. *ret_idx = i + 1;
  64. return -1;
  65. }
  66. /* This function gets the character at the pstart position, interpreting UTF8 multybyte sequences
  67. and returns the pointer to the next character */
  68. uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
  69. uint32_t val = 0;
  70. uint8_t *p = pstart;
  71. uint8_t valcur = cb_read_byte(p);
  72. if (0 == (0x80 & valcur)) {
  73. val = valcur;
  74. p++;
  75. }
  76. else if (0xC0 == (0xE0 & valcur)) {
  77. val = valcur & 0x1F;
  78. val <<= 6;
  79. p++;
  80. valcur = cb_read_byte(p);
  81. val |= (valcur & 0x3F);
  82. p++;
  83. }
  84. else if (0xE0 == (0xF0 & valcur)) {
  85. val = valcur & 0x0F;
  86. val <<= 6; p++;
  87. valcur = cb_read_byte(p);
  88. val |= (valcur & 0x3F);
  89. val <<= 6; p++;
  90. valcur = cb_read_byte(p);
  91. val |= (valcur & 0x3F);
  92. p++;
  93. }
  94. else if (0xF0 == (0xF8 & valcur)) {
  95. val = valcur & 0x07;
  96. val <<= 6; p++;
  97. valcur = cb_read_byte(p);
  98. val |= (valcur & 0x3F);
  99. val <<= 6; p++;
  100. valcur = cb_read_byte(p);
  101. val |= (valcur & 0x3F);
  102. val <<= 6; p++;
  103. valcur = cb_read_byte(p);
  104. val |= (valcur & 0x3F);
  105. p++;
  106. }
  107. else if (0xF8 == (0xFC & valcur)) {
  108. val = valcur & 0x03;
  109. val <<= 6; p++;
  110. valcur = cb_read_byte(p);
  111. val |= (valcur & 0x3F);
  112. val <<= 6; p++;
  113. valcur = cb_read_byte(p);
  114. val |= (valcur & 0x3F);
  115. val <<= 6; p++;
  116. valcur = cb_read_byte(p);
  117. val |= (valcur & 0x3F);
  118. val <<= 6; p++;
  119. valcur = cb_read_byte(p);
  120. val |= (valcur & 0x3F);
  121. p++;
  122. }
  123. else if (0xFC == (0xFE & valcur)) {
  124. val = valcur & 0x01;
  125. val <<= 6; p++;
  126. valcur = cb_read_byte(p);
  127. val |= (valcur & 0x3F);
  128. val <<= 6; p++;
  129. valcur = cb_read_byte(p);
  130. val |= (valcur & 0x3F);
  131. val <<= 6; p++;
  132. valcur = cb_read_byte(p);
  133. val |= (valcur & 0x3F);
  134. val <<= 6; p++;
  135. valcur = cb_read_byte(p);
  136. val |= (valcur & 0x3F);
  137. val <<= 6; p++;
  138. valcur = cb_read_byte(p);
  139. val |= (valcur & 0x3F);
  140. p++;
  141. }
  142. else if (0x80 == (0xC0 & valcur))
  143. for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
  144. else
  145. for (; ((0xFE & valcur) > 0xFC); ) { p++; valcur = cb_read_byte(p); }
  146. if (pval) *pval = val;
  147. return p;
  148. }
  149. static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
  150. uint8_t cnt = 0;
  151. uint8_t *pnext = (uint8_t *)pstart;
  152. for (;;) {
  153. wchar_t ch;
  154. pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
  155. if (!ch) break;
  156. cnt++;
  157. }
  158. return cnt;
  159. }
  160. uint8_t utf8_strlen(const char *pstart) {
  161. return utf8_strlen_cb(pstart, read_byte_ram);
  162. }
  163. uint8_t utf8_strlen_P(PGM_P pstart) {
  164. return utf8_strlen_cb(pstart, read_byte_rom);
  165. }