Newer
Older
/**
* @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);
}
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* @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;
if (num_data < 1) {
*ret_idx = 0;
return -1;
}
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;
return -1;
}
/* This function gets the character at the pstart position, interpreting UTF8 multybyte sequences
and returns the pointer to the next character */
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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;
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))
for (; 0x80 == (0xC0 & valcur); ) { p++; valcur = cb_read_byte(p); }
for (; ((0xFE & valcur) > 0xFC); ) { p++; valcur = cb_read_byte(p); }
if (pval) *pval = val;
return p;
}
static inline uint8_t utf8_strlen_cb(const char *pstart, read_byte_cb_t cb_read_byte) {
uint8_t cnt = 0;
uint8_t *pnext = (uint8_t *)pstart;
for (;;) {
wchar_t ch;
pnext = get_utf8_value_cb(pnext, cb_read_byte, &ch);
if (!ch) break;
cnt++;
}
return cnt;
}
uint8_t utf8_strlen(const char *pstart) {
return utf8_strlen_cb(pstart, read_byte_ram);
uint8_t utf8_strlen_P(PGM_P pstart) {
return utf8_strlen_cb(pstart, read_byte_rom);