1 /*
2 * File: gl_font.c
3 * Author: TeslaRus
4 *
5 * Created on January 16, 2015, 10:46 PM
6 */
7
8 #include <stdint.h>
9 #include <string.h>
10 #include "utf8_32.h"
11
12
utf8_next_symbol(uint8_t * utf8)13 static uint8_t *utf8_next_symbol(uint8_t *utf8)
14 {
15 uint8_t b = *utf8;
16
17 // save ASC symbol as is
18 if(!(b & 0x80))
19 {
20 return utf8 + 1;
21 }
22
23 // calculate lenght
24 while(b & 0x80)
25 {
26 b <<= 1;
27 utf8++;
28 }
29
30 return utf8;
31 }
32
33
utf8_strlen(const char * str)34 uint32_t utf8_strlen(const char *str)
35 {
36 uint32_t i = 0;
37 uint8_t *ch = (uint8_t*)str;
38
39 for(; *ch; i++)
40 {
41 ch = utf8_next_symbol(ch);
42 }
43
44 return i;
45 }
46
47
utf8_to_utf32(uint8_t * utf8,uint32_t * utf32)48 uint8_t *utf8_to_utf32(uint8_t *utf8, uint32_t *utf32)
49 {
50 uint8_t *u_utf8 = utf8;
51 uint8_t b = *u_utf8++;
52 uint32_t c, shift;
53 int len = 0;
54
55 // save ASC symbol as is
56 if(!(b & 0x80))
57 {
58 *utf32 = b;
59 return utf8 + 1;
60 }
61
62 // calculate lenght
63 while(b & 0x80)
64 {
65 b <<= 1;
66 ++len;
67 }
68
69 c = b;
70 shift = 6 - len;
71
72 while(--len)
73 {
74 c <<= shift;
75 c |= (*u_utf8++) & 0x3f;
76 shift = 6;
77 }
78
79 *utf32 = c;
80 return u_utf8;
81 }
82
83
utf32_to_utf8(uint8_t utf8[6],uint32_t utf32)84 uint32_t utf32_to_utf8(uint8_t utf8[6], uint32_t utf32)
85 {
86 uint32_t utf8_len = 0;
87 if((utf32 & (~0x0000007F)) == 0)
88 {
89 utf8[0] = 0x0000007F & utf32;
90 utf8_len = 1;
91 }
92 else if((utf32 & (~0x000007FF)) == 0)
93 {
94 utf8[1] = (0x0000003F & utf32) | 0x80;
95 utf32 >>= 6;
96 utf8[0] = (0x0000003F & utf32) | 0xC0;
97 utf8_len = 2;
98 }
99 else if((utf32 & (~0x0000FFFF)) == 0)
100 {
101 utf8[2] = (0x0000003F & utf32) | 0x80;
102 utf32 >>= 6;
103 utf8[1] = (0x0000003F & utf32) | 0x80;
104 utf32 >>= 6;
105 utf8[0] = (0x0000003F & utf32) | 0xE0;
106 utf8_len = 3;
107 }
108 else if((utf32 & (~0x001FFFFF)) == 0)
109 {
110 utf8[3] = (0x0000003F & utf32) | 0x80;
111 utf32 >>= 6;
112 utf8[2] = (0x0000003F & utf32) | 0x80;
113 utf32 >>= 6;
114 utf8[1] = (0x0000003F & utf32) | 0x80;
115 utf32 >>= 6;
116 utf8[0] = (0x0000003F & utf32) | 0xF0;
117 utf8_len = 4;
118 }
119 else if((utf32 & (~0x03FFFFFF)) == 0)
120 {
121 utf8[4] = (0x0000003F & utf32) | 0x80;
122 utf32 >>= 6;
123 utf8[3] = (0x0000003F & utf32) | 0x80;
124 utf32 >>= 6;
125 utf8[2] = (0x0000003F & utf32) | 0x80;
126 utf32 >>= 6;
127 utf8[1] = (0x0000003F & utf32) | 0x80;
128 utf32 >>= 6;
129 utf8[0] = (0x0000003F & utf32) | 0xF8;
130 utf8_len = 5;
131 }
132 else if((utf32 & (~0x7FFFFFFF)) == 0)
133 {
134 utf8[5] = (0x0000003F & utf32) | 0x80;
135 utf32 >>= 6;
136 utf8[4] = (0x0000003F & utf32) | 0x80;
137 utf32 >>= 6;
138 utf8[3] = (0x0000003F & utf32) | 0x80;
139 utf32 >>= 6;
140 utf8[2] = (0x0000003F & utf32) | 0x80;
141 utf32 >>= 6;
142 utf8[1] = (0x0000003F & utf32) | 0x80;
143 utf32 >>= 6;
144 utf8[0] = (0x0000003F & utf32) | 0xFC;
145 utf8_len = 6;
146 }
147
148 return utf8_len;
149 }
150
151
utf8_delete_char(uint8_t * utf8,uint32_t pos)152 void utf8_delete_char(uint8_t *utf8, uint32_t pos)
153 {
154 uint32_t i = 0;
155 uint8_t *ch = utf8;
156
157 for(; *ch && i < pos; i++)
158 {
159 ch = utf8_next_symbol(ch);
160 }
161
162 if((i == pos) && *ch)
163 {
164 int len = 0;
165 uint8_t b = *ch;
166 uint8_t *next_ch;
167 while(b & 0x80)
168 {
169 b <<= 1;
170 ++len;
171 }
172 len = (len == 0) ? (1) : (len);
173
174 for(next_ch = ch + len; *next_ch; ch++, next_ch++)
175 {
176 *ch = *next_ch;
177 }
178 *ch = 0;
179 }
180 }
181
182
utf8_insert_char(uint8_t * utf8,uint32_t utf32,uint32_t pos,uint32_t size)183 void utf8_insert_char(uint8_t *utf8, uint32_t utf32, uint32_t pos, uint32_t size)
184 {
185 uint32_t i = 0;
186 uint8_t *ch = utf8;
187
188 for(; *ch && i < pos; i++)
189 {
190 ch = utf8_next_symbol(ch);
191 }
192
193 if(i == pos)
194 {
195 uint8_t new_char[8] = { 0 };
196 uint32_t utf8_len = utf32_to_utf8(new_char, utf32);
197 uint32_t old_len = strlen((const char*)utf8);
198 if((utf8_len > 0) && (old_len + utf8_len < size))
199 {
200 uint8_t *tch = utf8 + old_len;
201 for(; tch != ch; tch--)
202 {
203 *(tch + utf8_len) = *tch;
204 }
205 *(tch + utf8_len) = *tch;
206 for(; utf8_len; utf8_len--)
207 {
208 ch[utf8_len-1] = new_char[utf8_len-1];
209 }
210 }
211 }
212 }