123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- /**
- * @file fontutils.cpp
- * @brief help functions for font and char
- * @author Yunhui Fu (yhfudev@gmail.com)
- * @version 1.0
- * @date 2016-08-19
- * @copyright GPL/BSD
- */
-
- #include "../inc/MarlinConfig.h"
-
- #if ENABLED(ULTRA_LCD)
- #include "ultralcd.h"
- #include "../Marlin.h"
- #endif
-
- #include "fontutils.h"
-
- uint8_t read_byte_ram(uint8_t * str) { return *str; }
- uint8_t read_byte_rom(uint8_t * str) { return pgm_read_byte(str); }
-
- #if DEBUG
- #ifdef ARDUINO
- #include <Arduino.h>
- #include <stdarg.h>
-
- void serial_printf_P(const char *format, ...) {
- static char buff[128];
- va_list args;
- va_start(args,format);
- vsnprintf_P(buff,sizeof(buff),format,args);
- va_end(args);
- buff[sizeof(buff)/sizeof(buff[0])-1]='\0';
-
- //Serial.print(buff);
- SERIAL_ECHO(buff); SERIAL_EOL;
- }
- #endif
- #endif
-
-
- #ifdef __WIN32__ // or whatever
- #define PRIiSZ "ld"
- #define PRIuSZ "Iu"
- #else
- #define PRIiSZ "zd"
- #define PRIuSZ "zu"
- #endif
- #define PRIiOFF "lld"
- #define PRIuOFF "llu"
-
-
- #define DBGMSG(a,b, ...) TRACE( #__VA_ARGS__ )
-
- //typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin); /*"data_list[idx] - *data_pin"*/
- /**
- * @brief 折半方式查找记录
- *
- * @param userdata : 用户数据指针
- * @param num_data : 数据个数
- * @param cb_comp : 比较两个数据的回调函数
- * @param data_pinpoint : 所要查找的 匹配数据指针
- * @param ret_idx : 查找到的位置;如果没有找到,则返回如添加该记录时其所在的位置。
- *
- * @return 找到则返回0,否则返回<0
- *
- * 折半方式查找记录, psl->marr 中指向的数据已经以先小后大方式排好序
- */
- /**
- * @brief Using binary search to find the position by data_pin
- *
- * @param userdata : User's data
- * @param num_data : the item number of the sorted data
- * @param cb_comp : the callback function to compare the user's data and pin
- * @param data_pin : The reference data to be found
- * @param ret_idx : the position of the required data; If failed, then it is the failed position, which is the insert position if possible.
- *
- * @return 0 on found, <0 on failed(fail position is saved by ret_idx)
- *
- * Using binary search to find the position by data_pin. The user's data should be sorted.
- */
- int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx) {
- int retcomp;
-
- FU_ASSERT(NULL != ret_idx);
- /* 查找合适的位置 */
- if (num_data < 1) {
- *ret_idx = 0;
- DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_ERROR, "num_data(%" PRIuSZ ") < 1", num_data);
- return -1;
- }
-
- /* 折半查找 */
- /* 为了不出现负数,以免缩小索引的所表示的数据范围
- * (负数表明减少一位二进制位的使用),
- * 内部 ileft 和 iright使用从1开始的下标,
- * 即1表示C语言中的0, 2表示语言中的1,以此类推。
- * 对外还是使用以 0 为开始的下标
- */
- size_t i = 0, ileft = 1, iright = num_data;
- bool flg_found = false;
- for (; ileft <= iright;) {
- i = (ileft + iright) / 2 - 1;
- /* cb_comp should return the *userdata[i] - *data_pinpoint */
- retcomp = cb_comp (userdata, i, data_pinpoint);
- if (retcomp > 0)
- iright = i;
- else if (retcomp < 0)
- ileft = i + 2;
- else {
- /* found ! */
- flg_found = true;
- break;
- }
- }
-
- if (flg_found) {
- *ret_idx = i;
- return 0;
- }
- if (iright <= i)
- *ret_idx = i;
- else if (ileft >= i + 2)
- *ret_idx = i + 1;
- //DBGMSG (PFDBG_CATLOG_PF, PFDBG_LEVEL_DEBUG, "not found! num_data=%" PRIuSZ "; ileft=%" PRIuSZ ", iright=%" PRIuSZ ", i=%" PRIuSZ "", num_data, ileft, iright, i);
- return -1;
- }
-
- /**
- * @brief 转换 UTF-8 编码的一个字符为本地的 Unicode 字符(wchar_t)
- *
- * @param pstart : 存储 UTF-8 字符的指针
- * @param cb_read_byte : 读取字符的函数;用于8位MCU ROM
- * @param pval : 需要返回的 Unicode 字符存放地址指针
- *
- * @return 成功返回下个 UTF-8 字符的位置
- *
- * 转换 UTF-8 编码的一个字符为本地的 Unicode 字符(wchar_t)
- */
- uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
- uint32_t val = 0;
- uint8_t *p = pstart;
-
- FU_ASSERT(NULL != pstart);
- FU_ASSERT(NULL != cb_read_byte);
-
- uint8_t valcur = cb_read_byte(p);
- if (0 == (0x80 & valcur)) {
- val = valcur;
- p++;
- }
- else if (0xC0 == (0xE0 & valcur)) {
- val = valcur & 0x1F;
- val <<= 6;
- p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- p++;
- }
- else if (0xE0 == (0xF0 & valcur)) {
- val = valcur & 0x0F;
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- p++;
- }
- else if (0xF0 == (0xF8 & valcur)) {
- val = valcur & 0x07;
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- p++;
- }
- else if (0xF8 == (0xFC & valcur)) {
- val = valcur & 0x03;
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- p++;
- }
- else if (0xFC == (0xFE & valcur)) {
- val = valcur & 0x01;
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- val <<= 6; p++;
- valcur = cb_read_byte(p);
- val |= (valcur & 0x3F);
- p++;
- }
- else if (0x80 == (0xC0 & valcur)) {
- /* error? */
- TRACE("ERR 1");
- for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
- }
- else {
- /* error */
- TRACE("ERR 2");
- for (; ((0xFE & valcur) > 0xFC); ) { p++; valcur = cb_read_byte(p); }
- }
- /*
- if (val == 0) {
- p = NULL;
- */
- /*
- }
- else if (pstart + maxlen < p) {
- p = pstart;
- if (pval) *pval = 0;
- }
- */
-
- if (pval) *pval = val;
-
- return p;
- }
-
- // uint8_t * get_utf8_value_cb (uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
- int utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
- wchar_t ch;
- uint8_t *pnext;
- int cnt = 0;
-
- for (pnext = (uint8_t *)pstart; ; ) {
- pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
- if (pnext == NULL || ch == 0) break;
- cnt++;
- TRACE("cnt=%d, ch=0x%X", cnt, (int)ch);
- }
- return cnt;
- }
-
- int
- my_strlen_P(const char *pstart)
- {
- const char *p;
- FU_ASSERT(NULL != pstart);
- p = pstart;
- while (p && pgm_read_byte(p) != '\0') p ++;
- return (p - pstart);
- }
-
- uint8_t utf8_strlen(const char *pstart) { return utf8_strlen_cb(pstart, read_byte_ram); }
- uint8_t utf8_strlen_P(const char *pstart) { return utf8_strlen_cb(pstart, read_byte_rom); }
-
- char* utf8_strncpy_cb( char * destination, const char *source, size_t num, int len_src, read_byte_cb_t cb_read_byte) {
- uint8_t *p = (uint8_t *)source;
- uint8_t *d = (uint8_t *)destination;
-
- FU_ASSERT(NULL != destination);
- FU_ASSERT(NULL != source);
- FU_ASSERT(NULL != cb_read_byte);
-
- uint8_t *pend = p + len_src;
-
- while (p < pend) {
- uint8_t valcur = cb_read_byte(p);
- size_t len = 0;
- if (0 == (0x80 & valcur))
- len = 1;
- else if (0xC0 == (0xE0 & valcur))
- len = 2;
- else if (0xE0 == (0xF0 & valcur))
- len = 3;
- else if (0xF0 == (0xF8 & valcur))
- len = 4;
- else if (0xF8 == (0xFC & valcur))
- len = 5;
- else if (0xFC == (0xFE & valcur))
- len = 6;
- else if (0x80 == (0xC0 & valcur)) {
- /* error? */
- for (; 0x80 == (0xC0 & valcur) && (p < pend); ) { p++; valcur = cb_read_byte(p); }
- }
- else {
- /* error */
- for (; ((0xFE & valcur) > 0xFC) && (p < pend); ) { p++; valcur = cb_read_byte(p); }
- }
- if (len < num) {
- for (size_t i = 0; i < len; i++) {
- valcur = cb_read_byte(p);
- *d = valcur;
- d++;
- p++;
- }
- }
- else
- break;
- }
- *d = 0;
- return destination;
- }
-
- char* utf8_strncpy(char * destination, const char * source, size_t num) {
- return utf8_strncpy_cb(destination, source, num, strlen(source), read_byte_ram);
- }
-
- char* utf8_strncpy_P(char * destination, const char * source, size_t num) {
- return utf8_strncpy_cb(destination, source, num, my_strlen_P(source), read_byte_rom);
- }
|