mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
264 lines
7.7 KiB
C
264 lines
7.7 KiB
C
|
/**
|
|||
|
* @file lv_txt_ap.c
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
/*********************
|
|||
|
* INCLUDES
|
|||
|
*********************/
|
|||
|
#include <stddef.h>
|
|||
|
#include "lv_bidi.h"
|
|||
|
#include "lv_txt.h"
|
|||
|
#include "lv_conf.h"
|
|||
|
#include "lv_txt_ap.h"
|
|||
|
#include "../lv_draw/lv_draw.h"
|
|||
|
|
|||
|
|
|||
|
/*********************
|
|||
|
* DEFINES
|
|||
|
*********************/
|
|||
|
|
|||
|
/**********************
|
|||
|
* TYPEDEFS
|
|||
|
**********************/
|
|||
|
|
|||
|
/**********************
|
|||
|
* STATIC PROTOTYPES
|
|||
|
**********************/
|
|||
|
static uint32_t lv_ap_get_char_index(uint16_t c);
|
|||
|
#if LV_USE_REVERSE_ARABIC_PERSIAN_CHARS == 1
|
|||
|
static void lv_ap_normalize_chars(uint32_t * str,uint16_t count);
|
|||
|
#endif
|
|||
|
|
|||
|
/**********************
|
|||
|
* STATIC VARIABLES
|
|||
|
**********************/
|
|||
|
|
|||
|
#if LV_USE_ARABIC_PERSIAN_CHARS == 1
|
|||
|
const ap_chars_map_t ap_chars_map[]={
|
|||
|
/* {Key Offset, End, Beginning, Middle, Isolated, {conjunction}} */
|
|||
|
{1 , 0xFE84, -1, 0, -1, {1, 0}}, // أ
|
|||
|
{2 , 0xFE86, -1, 0, -1, {1, 0}}, // ؤ
|
|||
|
{3 , 0xFE88, -1, 0, -1, {1, 0}}, // ﺇ
|
|||
|
{4 , 0xFE8A, 1, 2, -1, {1, 0}}, // ئ
|
|||
|
{5 , 0xFE8E, -1, 0, -1, {1, 0}}, // آ
|
|||
|
{6 , 0xFE90, 1, 2, -1, {1, 1}}, // ب
|
|||
|
{92 , 0xFB57, 1, 2, -1, {1, 1}}, // پ
|
|||
|
{8 , 0xFE96, 1, 2, -1, {1, 1}}, // ت
|
|||
|
{9 , 0xFE9A, 1, 2, -1, {1, 1}}, // ث
|
|||
|
{10 , 0xFE9E, 1, 2, -1, {1, 1}}, // ج
|
|||
|
{100, 0xFB7B, 1, 2, -1, {1, 1}}, // چ
|
|||
|
{11 , 0xFEA2, 1, 2, -1, {1, 1}}, // ح
|
|||
|
{12 , 0xFEA6, 1, 2, -1, {1, 1}}, // خ
|
|||
|
{13 , 0xFEAA, -1, 0, -1, {1, 0}}, // د
|
|||
|
{14 , 0xFEAC, -1, 0, -1, {1, 0}}, // ذ
|
|||
|
{15 , 0xFEAE, -1, 0, -1, {1, 0}}, // ر
|
|||
|
{16 , 0xFEB0, -1, 0, -1, {1, 0}}, // ز
|
|||
|
{118, 0xFB8B, -1, 0, -1, {1, 0}}, // ژ
|
|||
|
{17 , 0xFEB2, 1, 2, -1, {1, 1}}, // س
|
|||
|
{18 , 0xFEB6, 1, 2, -1, {1, 1}}, // ش
|
|||
|
{19 , 0xFEBA, 1, 2, -1, {1, 1}}, // ص
|
|||
|
{20 , 0xFEBE, 1, 2, -1, {1, 1}}, // ض
|
|||
|
{21 , 0xFEC2, 1, 2, -1, {1, 1}}, // ط
|
|||
|
{22 , 0xFEC6, 1, 2, -1, {1, 1}}, // ظ
|
|||
|
{23 , 0xFECA, 1, 2, -1, {1, 1}}, // ع
|
|||
|
{24 , 0xFECE, 1, 2, -1, {1, 1}}, // غ
|
|||
|
{31 , 0xFED2, 1, 2, -1, {1, 1}}, // ف
|
|||
|
{32 , 0xFED6, 1, 2, -1, {1, 1}}, // ق
|
|||
|
{135, 0xFB8F, 1, 2, -1, {1, 1}}, // ک
|
|||
|
{33, 0xFEDA, 1, 2, -1, {1, 1}}, // ﻙ
|
|||
|
{141, 0xFB93, 1, 2, -1, {1, 1}}, // گ
|
|||
|
{34 , 0xFEDE, 1, 2, -1, {1, 1}}, // ل
|
|||
|
{35 , 0xFEE2, 1, 2, -1, {1, 1}}, // م
|
|||
|
{36 , 0xFEE6, 1, 2, -1, {1, 1}}, // ن
|
|||
|
{38 , 0xFEEE, -1, 0, -1, {1, 0}}, // و
|
|||
|
{37 , 0xFEEA, 1, 2, -1, {1, 1}}, // ه
|
|||
|
{39 , 0xFBFD, 1, 2, -1, {1, 1}}, // ي
|
|||
|
{40 , 0xFEF2, 1, 2, -1, {1, 1}}, // ي
|
|||
|
{170 , 0xFBFD, 1, 2, -1, {1, 1}}, // ی
|
|||
|
{7 , 0xFE94, 1, 2, -1, {1, 0}}, // ة
|
|||
|
{206, 0x06F0, 1, 2, -1, {0, 0}}, // ۰
|
|||
|
{207, 0x06F1, 0, 0, 0, {0, 0}}, // ۱
|
|||
|
{208, 0x06F2, 0, 0, 0, {0, 0}}, // ۲
|
|||
|
{209, 0x06F3, 0, 0, 0, {0, 0}}, // ۳
|
|||
|
{210, 0x06F4, 0, 0, 0, {0, 0}}, // ۴
|
|||
|
{211, 0x06F5, 0, 0, 0, {0, 0}}, // ۵
|
|||
|
{212, 0x06F6, 0, 0, 0, {0, 0}}, // ۶
|
|||
|
{213, 0x06F7, 0, 0, 0, {0, 0}}, // ۷
|
|||
|
{214, 0x06F8, 0, 0, 0, {0, 0}}, // ۸
|
|||
|
{215, 0x06F9, 0, 0, 0, {0, 0}}, // ۹
|
|||
|
LV_AP_END_CHARS_LIST
|
|||
|
};
|
|||
|
/**********************
|
|||
|
* MACROS
|
|||
|
**********************/
|
|||
|
|
|||
|
/**********************
|
|||
|
* GLOBAL FUNCTIONS
|
|||
|
**********************/
|
|||
|
uint32_t lv_txt_ap_calc_bytes_cnt(const char * txt){
|
|||
|
uint32_t txt_length = 0;
|
|||
|
uint32_t chars_cnt = 0;
|
|||
|
uint32_t current_ap_idx = 0;
|
|||
|
uint32_t i, j;
|
|||
|
uint32_t ch_enc;
|
|||
|
|
|||
|
txt_length = lv_txt_get_encoded_length(txt);
|
|||
|
|
|||
|
i=0;
|
|||
|
j=0;
|
|||
|
while(i<txt_length){
|
|||
|
ch_enc = lv_txt_encoded_next(txt, &j);
|
|||
|
current_ap_idx = lv_ap_get_char_index(ch_enc);
|
|||
|
|
|||
|
if(current_ap_idx != LV_UNDEF_ARABIC_PERSIAN_CHARS)
|
|||
|
ch_enc = ap_chars_map[current_ap_idx].char_end_form;
|
|||
|
|
|||
|
if(ch_enc <=0x7F)
|
|||
|
chars_cnt++;
|
|||
|
else if(ch_enc <=0x7FFF)
|
|||
|
chars_cnt+=2;
|
|||
|
else
|
|||
|
chars_cnt+=3;
|
|||
|
|
|||
|
i++;
|
|||
|
}
|
|||
|
|
|||
|
return chars_cnt + 1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void lv_txt_ap_proc(const char * txt,char * txt_out){
|
|||
|
uint32_t txt_length=0;
|
|||
|
uint32_t index_current,idx_next,idx_previous,i,j;
|
|||
|
uint32_t * ch_enc;
|
|||
|
char * txt_out_temp;
|
|||
|
|
|||
|
txt_length = lv_txt_get_encoded_length(txt);
|
|||
|
|
|||
|
ch_enc = (uint32_t *)lv_mem_alloc(sizeof(uint32_t) * txt_length);
|
|||
|
|
|||
|
i=0;
|
|||
|
j=0;
|
|||
|
while(j<txt_length)
|
|||
|
ch_enc[j++] = lv_txt_encoded_next(txt, &i);
|
|||
|
|
|||
|
i=0;
|
|||
|
idx_previous = LV_UNDEF_ARABIC_PERSIAN_CHARS;
|
|||
|
while(i<txt_length){
|
|||
|
index_current = lv_ap_get_char_index(ch_enc[i]);
|
|||
|
idx_next = lv_ap_get_char_index(ch_enc[i+1]);
|
|||
|
|
|||
|
if(index_current == LV_UNDEF_ARABIC_PERSIAN_CHARS)
|
|||
|
{
|
|||
|
i++;
|
|||
|
idx_previous = LV_UNDEF_ARABIC_PERSIAN_CHARS;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
uint8_t conjunction_to_previuse = (i==0 || idx_previous == LV_UNDEF_ARABIC_PERSIAN_CHARS) ? 0 : ap_chars_map[idx_previous].ap_chars_conjunction.conj_to_next;
|
|||
|
uint8_t conjunction_to_next = ((i==txt_length-1) || idx_next == LV_UNDEF_ARABIC_PERSIAN_CHARS) ? 0 : ap_chars_map[idx_next].ap_chars_conjunction.conj_to_previous;
|
|||
|
|
|||
|
if(conjunction_to_previuse && conjunction_to_next)
|
|||
|
ch_enc[i] = ap_chars_map[index_current].char_end_form+ap_chars_map[index_current].char_middle_form_offset;
|
|||
|
else if(!conjunction_to_previuse && conjunction_to_next)
|
|||
|
ch_enc[i] = ap_chars_map[index_current].char_end_form+ap_chars_map[index_current].char_begining_form_offset;
|
|||
|
else if(conjunction_to_previuse && !conjunction_to_next)
|
|||
|
ch_enc[i] = ap_chars_map[index_current].char_end_form;
|
|||
|
else
|
|||
|
ch_enc[i] = ap_chars_map[index_current].char_end_form+ap_chars_map[index_current].char_isolated_form_offset;
|
|||
|
idx_previous = index_current;
|
|||
|
i++;
|
|||
|
}
|
|||
|
|
|||
|
#if LV_USE_REVERSE_ARABIC_PERSIAN_CHARS == 1
|
|||
|
lv_ap_normalize_chars(ch_enc,txt_length);
|
|||
|
#endif
|
|||
|
|
|||
|
txt_out_temp = txt_out;
|
|||
|
i=0;
|
|||
|
while(i<txt_length){
|
|||
|
if((*ch_enc) <=0x7F){
|
|||
|
*(txt_out_temp++) = *ch_enc;
|
|||
|
}else if((*ch_enc) <=0x7FFF){
|
|||
|
*(txt_out_temp++) = 0xC0 | ((*ch_enc>>6) & 0x3F);
|
|||
|
*(txt_out_temp++) = 0x80 | (*ch_enc & 0x3F);
|
|||
|
}else {
|
|||
|
*(txt_out_temp++) = 0xE0 | ((*ch_enc>>12) & 0x3F);
|
|||
|
*(txt_out_temp++) = 0x80 | ((*ch_enc>>6) & 0x3F);
|
|||
|
*(txt_out_temp++) = 0x80 | (*ch_enc & 0x3F);
|
|||
|
}
|
|||
|
ch_enc++;
|
|||
|
i++;
|
|||
|
}
|
|||
|
*(txt_out_temp++)=0;
|
|||
|
lv_mem_free(ch_enc);
|
|||
|
}
|
|||
|
/**********************
|
|||
|
* STATIC FUNCTIONS
|
|||
|
**********************/
|
|||
|
|
|||
|
static uint32_t lv_ap_get_char_index(uint16_t c){
|
|||
|
for(uint8_t i=0;ap_chars_map[i].char_end_form;i++){
|
|||
|
if(c == (ap_chars_map[i].char_offset + LV_AP_ALPHABET_BASE_CODE))
|
|||
|
return i;
|
|||
|
}
|
|||
|
return LV_UNDEF_ARABIC_PERSIAN_CHARS;
|
|||
|
}
|
|||
|
|
|||
|
#if LV_USE_REVERSE_ARABIC_PERSIAN_CHARS == 1
|
|||
|
static void lv_ap_normalize_chars(uint32_t * str,uint16_t count){
|
|||
|
uint16_t t,u,i=0,j,is_digit_domin=0,digit_domin_s=0,is_ascii_domin=0,ascii_domin_s=0;
|
|||
|
while(i<count){
|
|||
|
if(str[i]>=0x06F0 && str[i]<=0x06F9){
|
|||
|
if(is_digit_domin==0)
|
|||
|
digit_domin_s = i;
|
|||
|
is_digit_domin = 1;
|
|||
|
}else if(is_digit_domin){
|
|||
|
for(j=0;j<(i-digit_domin_s)/2;j++){
|
|||
|
t = str[j+digit_domin_s];
|
|||
|
str[j+digit_domin_s] = str[i-j-1];
|
|||
|
str[i-j-1] = t;
|
|||
|
}
|
|||
|
is_digit_domin = 0;
|
|||
|
}
|
|||
|
|
|||
|
if((str[i] & 0x80) == 0){
|
|||
|
if(is_ascii_domin==0)
|
|||
|
ascii_domin_s = i;
|
|||
|
is_ascii_domin = 1;
|
|||
|
}else if(is_ascii_domin){
|
|||
|
for(j=0;j<(i-ascii_domin_s)/2;j++){
|
|||
|
u = str[j+ascii_domin_s];
|
|||
|
str[j+ascii_domin_s] = str[i-j-1];
|
|||
|
str[i-j-1] = u;
|
|||
|
}
|
|||
|
is_ascii_domin = 0;
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
if(is_ascii_domin){
|
|||
|
for(j=0;j<(count-ascii_domin_s)/2;j++){
|
|||
|
u = str[j+ascii_domin_s];
|
|||
|
str[j+ascii_domin_s] = str[i-j-1];
|
|||
|
str[i-j-1] = u;
|
|||
|
}
|
|||
|
}
|
|||
|
if(is_digit_domin){
|
|||
|
for(j=0;j<(count-digit_domin_s)/2;j++){
|
|||
|
t = str[j+digit_domin_s];
|
|||
|
str[j+digit_domin_s] = str[i-j-1];
|
|||
|
str[i-j-1] = t;
|
|||
|
}
|
|||
|
}
|
|||
|
i=0;
|
|||
|
while(i<count/2){
|
|||
|
t = str[i];
|
|||
|
str[i] = str[count-i-1];
|
|||
|
str[count-i-1] = t;
|
|||
|
i++;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
#endif
|