1 /**
2 * @file lv_txt_ap.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include <stddef.h>
10 #include "lv_bidi.h"
11 #include "lv_txt.h"
12 #include "lv_txt_ap.h"
13 #include "../lv_draw/lv_draw.h"
14
15
16 /*********************
17 * DEFINES
18 *********************/
19
20 /**********************
21 * TYPEDEFS
22 **********************/
23
24 /**********************
25 * STATIC PROTOTYPES
26 **********************/
27 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
28 static uint32_t lv_ap_get_char_index(uint16_t c);
29
30 /**********************
31 * STATIC VARIABLES
32 **********************/
33
34 const ap_chars_map_t ap_chars_map[] = {
35 /* {Key Offset, End, Beginning, Middle, Isolated, {conjunction}} */
36 {1, 0xFE84, -1, 0, -1, {1, 0}}, // أ
37 {2, 0xFE86, -1, 0, -1, {1, 0}}, // ؤ
38 {3, 0xFE88, -1, 0, -1, {1, 0}}, // ﺇ
39 {4, 0xFE8A, 1, 2, -1, {1, 0}}, // ئ
40 {5, 0xFE8E, -1, 0, -1, {1, 0}}, // آ
41 {6, 0xFE90, 1, 2, -1, {1, 1}}, // ب
42 {92, 0xFB57, 1, 2, -1, {1, 1}}, // پ
43 {8, 0xFE96, 1, 2, -1, {1, 1}}, // ت
44 {9, 0xFE9A, 1, 2, -1, {1, 1}}, // ث
45 {10, 0xFE9E, 1, 2, -1, {1, 1}}, // ج
46 {100, 0xFB7B, 1, 2, -1, {1, 1}}, // چ
47 {11, 0xFEA2, 1, 2, -1, {1, 1}}, // ح
48 {12, 0xFEA6, 1, 2, -1, {1, 1}}, // خ
49 {13, 0xFEAA, -1, 0, -1, {1, 0}}, // د
50 {14, 0xFEAC, -1, 0, -1, {1, 0}}, // ذ
51 {15, 0xFEAE, -1, 0, -1, {1, 0}}, // ر
52 {16, 0xFEB0, -1, 0, -1, {1, 0}}, // ز
53 {118, 0xFB8B, -1, 0, -1, {1, 0}}, // ژ
54 {17, 0xFEB2, 1, 2, -1, {1, 1}}, // س
55 {18, 0xFEB6, 1, 2, -1, {1, 1}}, // ش
56 {19, 0xFEBA, 1, 2, -1, {1, 1}}, // ص
57 {20, 0xFEBE, 1, 2, -1, {1, 1}}, // ض
58 {21, 0xFEC2, 1, 2, -1, {1, 1}}, // ط
59 {22, 0xFEC6, 1, 2, -1, {1, 1}}, // ظ
60 {23, 0xFECA, 1, 2, -1, {1, 1}}, // ع
61 {24, 0xFECE, 1, 2, -1, {1, 1}}, // غ
62 {31, 0xFED2, 1, 2, -1, {1, 1}}, // ف
63 {32, 0xFED6, 1, 2, -1, {1, 1}}, // ق
64 {135, 0xFB8F, 1, 2, -1, {1, 1}}, // ک
65 {33, 0xFEDA, 1, 2, -1, {1, 1}}, // ﻙ
66 {141, 0xFB93, 1, 2, -1, {1, 1}}, // گ
67 {34, 0xFEDE, 1, 2, -1, {1, 1}}, // ل
68 {35, 0xFEE2, 1, 2, -1, {1, 1}}, // م
69 {36, 0xFEE6, 1, 2, -1, {1, 1}}, // ن
70 {38, 0xFEEE, -1, 0, -1, {1, 0}}, // و
71 {37, 0xFEEA, 1, 2, -1, {1, 1}}, // ه
72 {39, 0xFBFD, 1, 2, -1, {1, 1}}, // ي
73 {40, 0xFEF2, 1, 2, -1, {1, 1}}, // ي
74 {170, 0xFBFD, 1, 2, -1, {1, 1}}, // ی
75 {7, 0xFE94, 1, 2, -1, {1, 0}}, // ة
76 {206, 0x06F0, 1, 2, -1, {0, 0}}, // ۰
77 {207, 0x06F1, 0, 0, 0, {0, 0}}, // ۱
78 {208, 0x06F2, 0, 0, 0, {0, 0}}, // ۲
79 {209, 0x06F3, 0, 0, 0, {0, 0}}, // ۳
80 {210, 0x06F4, 0, 0, 0, {0, 0}}, // ۴
81 {211, 0x06F5, 0, 0, 0, {0, 0}}, // ۵
82 {212, 0x06F6, 0, 0, 0, {0, 0}}, // ۶
83 {213, 0x06F7, 0, 0, 0, {0, 0}}, // ۷
84 {214, 0x06F8, 0, 0, 0, {0, 0}}, // ۸
85 {215, 0x06F9, 0, 0, 0, {0, 0}}, // ۹
86 LV_AP_END_CHARS_LIST
87 };
88 /**********************
89 * MACROS
90 **********************/
91
92 /**********************
93 * GLOBAL FUNCTIONS
94 **********************/
_lv_txt_ap_calc_bytes_cnt(const char * txt)95 uint32_t _lv_txt_ap_calc_bytes_cnt(const char * txt)
96 {
97 uint32_t txt_length = 0;
98 uint32_t chars_cnt = 0;
99 uint32_t current_ap_idx = 0;
100 uint32_t i, j;
101 uint32_t ch_enc;
102
103 txt_length = _lv_txt_get_encoded_length(txt);
104
105 i = 0;
106 j = 0;
107 while(i < txt_length) {
108 ch_enc = _lv_txt_encoded_next(txt, &j);
109 current_ap_idx = lv_ap_get_char_index(ch_enc);
110
111 if(current_ap_idx != LV_UNDEF_ARABIC_PERSIAN_CHARS)
112 ch_enc = ap_chars_map[current_ap_idx].char_end_form;
113
114 if(ch_enc < 0x80)
115 chars_cnt++;
116 else if(ch_enc < 0x0800)
117 chars_cnt += 2;
118 else if(ch_enc < 0x010000)
119 chars_cnt += 3;
120 else
121 chars_cnt += 4;
122
123 i++;
124 }
125
126 return chars_cnt + 1;
127 }
128
129
_lv_txt_ap_proc(const char * txt,char * txt_out)130 void _lv_txt_ap_proc(const char * txt, char * txt_out)
131 {
132 uint32_t txt_length = 0;
133 uint32_t index_current, idx_next, idx_previous, i, j;
134 uint32_t * ch_enc;
135 char * txt_out_temp;
136
137 txt_length = _lv_txt_get_encoded_length(txt);
138
139 ch_enc = (uint32_t *)lv_mem_alloc(sizeof(uint32_t) * (txt_length + 1));
140
141 i = 0;
142 j = 0;
143 while(j < txt_length)
144 ch_enc[j++] = _lv_txt_encoded_next(txt, &i);
145
146 ch_enc[j] = 0;
147
148 i = 0;
149 idx_previous = LV_UNDEF_ARABIC_PERSIAN_CHARS;
150 while(i < txt_length) {
151 index_current = lv_ap_get_char_index(ch_enc[i]);
152 idx_next = lv_ap_get_char_index(ch_enc[i + 1]);
153
154 if(index_current == LV_UNDEF_ARABIC_PERSIAN_CHARS) {
155 i++;
156 idx_previous = LV_UNDEF_ARABIC_PERSIAN_CHARS;
157 continue;
158 }
159
160 uint8_t conjunction_to_previuse = (i == 0 ||
161 idx_previous == LV_UNDEF_ARABIC_PERSIAN_CHARS) ? 0 : ap_chars_map[idx_previous].ap_chars_conjunction.conj_to_next;
162 uint8_t conjunction_to_next = ((i == txt_length - 1) ||
163 idx_next == LV_UNDEF_ARABIC_PERSIAN_CHARS) ? 0 : ap_chars_map[idx_next].ap_chars_conjunction.conj_to_previous;
164
165 if(conjunction_to_previuse && conjunction_to_next)
166 ch_enc[i] = ap_chars_map[index_current].char_end_form + ap_chars_map[index_current].char_middle_form_offset;
167 else if(!conjunction_to_previuse && conjunction_to_next)
168 ch_enc[i] = ap_chars_map[index_current].char_end_form + ap_chars_map[index_current].char_begining_form_offset;
169 else if(conjunction_to_previuse && !conjunction_to_next)
170 ch_enc[i] = ap_chars_map[index_current].char_end_form;
171 else
172 ch_enc[i] = ap_chars_map[index_current].char_end_form + ap_chars_map[index_current].char_isolated_form_offset;
173 idx_previous = index_current;
174 i++;
175 }
176
177 txt_out_temp = txt_out;
178 i = 0;
179
180 while(i < txt_length) {
181 if(ch_enc[i] < 0x80) {
182 *(txt_out_temp++) = ch_enc[i] & 0xFF;
183 }
184 else if(ch_enc[i] < 0x0800) {
185 *(txt_out_temp++) = ((ch_enc[i] >> 6) & 0x1F) | 0xC0;
186 *(txt_out_temp++) = ((ch_enc[i] >> 0) & 0x3F) | 0x80;
187 }
188 else if(ch_enc[i] < 0x010000) {
189 *(txt_out_temp++) = ((ch_enc[i] >> 12) & 0x0F) | 0xE0;
190 *(txt_out_temp++) = ((ch_enc[i] >> 6) & 0x3F) | 0x80;
191 *(txt_out_temp++) = ((ch_enc[i] >> 0) & 0x3F) | 0x80;
192 }
193 else if(ch_enc[i] < 0x110000) {
194 *(txt_out_temp++) = ((ch_enc[i] >> 18) & 0x07) | 0xF0;
195 *(txt_out_temp++) = ((ch_enc[i] >> 12) & 0x3F) | 0x80;
196 *(txt_out_temp++) = ((ch_enc[i] >> 6) & 0x3F) | 0x80;
197 *(txt_out_temp++) = ((ch_enc[i] >> 0) & 0x3F) | 0x80;
198 }
199
200 i++;
201 }
202 *(txt_out_temp) = '\0';
203 lv_mem_free(ch_enc);
204 }
205 /**********************
206 * STATIC FUNCTIONS
207 **********************/
208
lv_ap_get_char_index(uint16_t c)209 static uint32_t lv_ap_get_char_index(uint16_t c)
210 {
211 for(uint8_t i = 0; ap_chars_map[i].char_end_form; i++) {
212 if(c == (ap_chars_map[i].char_offset + LV_AP_ALPHABET_BASE_CODE))
213 return i;
214 }
215 return LV_UNDEF_ARABIC_PERSIAN_CHARS;
216 }
217
218 #endif
219