嵌入式中 动态阿拉伯语字符串 转换 LCD显示字符串【感谢建国雄心】
作者:互联网
本文参考CSDBN:建国雄心 的博客,这里找不到该帖子,放一个类似的仅供参考https://blog.csdn.net/qiaojiongzeng6321/article/details/74857245,实际代码因为字模脚本的问题跟大佬的有区别(字形转换地方)
阿语与其他语言有差异,阿语范围内字符需要从右向左写,中间碰到其他字符要从左向右写。
这里不考虑语法顺序和后面的练笔规则,转译后应为,0x600,0x63b,0x30,0x35,0x34,0x20,0x644,0x63c,在计算机显示时需要转成 0x63c,0x644,0x30,0x35,0x34,0x30,0x63b,0x600
连笔的规则不多说,感兴趣自己搜搜看,项目中一般使用的是python脚本转译的,有个项目接到了新需求,从外部接受到后动态显示,需求要求显示阿语,遂增加了此功能,使用时先用 gutCheckArabicReverse 接口检查是否有阿语需要反显,如果有通过 gutArabicSrcStrCovPrintStr 转换字符串。
Arbic_Position数组跟其他博客有区别,实际上字符字形都一样,可以忽略,这个问题主要是我手头字模和字形工具的问题,建议先copy其他人发布的数据结构,验证无问题即可
直接放干货,基于C语言
const uint16 Arbic_unicode[]={
0x621,0x622,0x623,0x624,0x625,0x626,0x627,0x628,0x629,0x62A,0x62B,0x62C,0x62D,0x62E,0x62F,
0x630,0x631,0x632,0x633,0x634,0x635,0x636,0x637,0x638,0x639,0x63A,0x63B,0x63C,0x63D,0x63E,0x63F,
0x640,0x641,0x642,0x643,0x644,0x645,0x646,0x647,0x648,0x649,0x64A
};
/*
The unicodes of alone are no mapping to Arabic Presentation Forms B area.
*/
const uint16 Arbic_Position[] = {
//# first, last, middle, alone
0x0621, 0x0621, 0x0621, 0x0621, //# 0xfe80),
0xfe82, 0x0622, 0xfe82, 0x0622, //# 0xfe81),
0xfe84, 0x0623, 0xfe84, 0x0623, //# 0xfe83),
0xfe86, 0x0624, 0xfe86, 0x0624, //# 0xfe85),
0xfe88, 0x0625, 0xfe88, 0x0625, //# 0xfe87),
0xfe8a, 0xfe8b, 0xfe8c, 0x0626, //# 0xfe89),
0xfe8e, 0x0627, 0xfe8e, 0x0627, //# 0xfe8d),
0xfe90, 0xfe91, 0xfe92, 0x0628, //# 0xfe8f),
0xfe94, 0x0629, 0xfe94, 0x0629, //# 0xfe93),
0xfe96, 0xfe97, 0xfe98, 0x062a, //# 0xfe95),
0xfe9a, 0xfe9b, 0xfe9c, 0x062b, //# 0xfe99),
0xfe9e, 0xfe9f, 0xfea0, 0x062c, //# 0xfe9d),
0xfea2, 0xfea3, 0xfea4, 0x062d, //# 0xfea1),
0xfea6, 0xfea7, 0xfea8, 0x062e, //# 0xfea5),
0xfeaa, 0x062f, 0xfeaa, 0x062f, //# 0xfea9),
0xfeac, 0x0630, 0xfeac, 0x0630, //# 0xfeab),
0xfeae, 0x0631, 0xfeae, 0x0631, //# 0xfead),
0xfeb0, 0x0632, 0xfeb0, 0x0632, //# 0xfeaf),
0xfeb2, 0xfeb3, 0xfeb4, 0x0633, //# 0xfeb1),
0xfeb6, 0xfeb7, 0xfeb8, 0x0634, //# 0xfeb5),
0xfeba, 0xfebb, 0xfebc, 0x0635, //# 0xfeb9),
0xfebe, 0xfebf, 0xfec0, 0x0636, //# 0xfebd),
0xfec2, 0xfec3, 0xfec4, 0x0637, //# 0xfec1),
0xfec6, 0xfec7, 0xfec8, 0x0638, //# 0xfec5),
0xfeca, 0xfecb, 0xfecc, 0x0639, //# 0xfec9),
0xfece, 0xfecf, 0xfed0, 0x063a, //# 0xfecd),
0x63b, 0x63b, 0x63b, 0x63b , //
0x63c, 0x63c, 0x63c, 0x63c , //
0x63d, 0x63d, 0x63d, 0x63d , //
0x63e, 0x63e, 0x63e, 0x63e , //
0x63f, 0x63f, 0x63f, 0x63f , //
0x640, 0x640, 0x640, 0x640 , //
0xfed2, 0xfed3, 0xfed4, 0x0641, //# 0xfed1),
0xfed6, 0xfed7, 0xfed8, 0x0642, //# 0xfed5),
0xfeda, 0xfedb, 0xfedc, 0x0643, //# 0xfed9),
0xfede, 0xfedf, 0xfee0, 0x0644, //# 0xfedd),
0xfee2, 0xfee3, 0xfee4, 0x0645, //# 0xfee1),
0xfee6, 0xfee7, 0xfee8, 0x0646, //# 0xfee5),
0xfeea, 0xfeeb, 0xfeec, 0x0647, //# 0xfee9),
0xfeee, 0x0648, 0xfeee, 0x0648, //# 0xfeed),
0xfef0, 0xfef3, 0xfef4, 0x0649, //# 0xfeef),
0xfef2, 0xfef3, 0xfef4, 0x064a //# 0xfef1))
};
/* 前连 - 当前字符 前一个字符 与 下表是否匹配 */
const uint16 U16FrontSet1[] = {
0x626,0x628,0x62a,0x62b,0x62c,0x62d,0x62e,
0x633,0x634,0x635,0x636,0x637,0x639,0x63a,
0x640,0x641,0x642,0x643,0x644,0x645,0x646,0x647,0x638,0x64a
};
/* 后连 - 当前字符 后一个字符 与 下表是否匹配 */
const uint16 U16BackSet2[] ={
0x622,0x623,0x624,0x625,0x626,0x627,0x628,0x629,0x62a,0x62b,0x62c,0x62d,0x62e,0x62f,
0x630,0x631,0x632,0x633,0x634,0x635,0x636,0x637,0x638,0x639,0x63a,
0x640,0x641,0x642,0x643,0x644,0x645,0x646,0x647,0x648,0x649, 0x64a,
};
/*-----------------------------------------
阿拉伯文连字符规则:
连字符是以0x644开头,后面跟的是0x622,0x623,0x625,0x627,并根据情况取下面的字符数组0或1,如果0x644前一个字符是在集合1(同上面的集合1)中间,那么取数组1,否则取数组0:
0x644 + 0x622/0x623/0x625/0x627,
n+0x644+append,
n = (U16FrontSet1) ,0x644 use index_1
else 0x644 use index_0
----------------------------------------- */
const uint16 arabic_specs[] ={
0xFEF5,0xFEF6, /* 0x622 */
0xFEF7,0xFEF8, /* 0x623 */
0xFEF9,0xFEFA, /* 0x625 */
0xFEFB,0xFEFC /* 0x627 */
};
//const uint16 head = 0x644;
//const uint16 append[] = {0x622,0x623,0x625,0x627};
#define pos_first 0
#define pos_last 1
#define pos_middle 2
#define pos_alone 3
/** ---------------------------
Araboc unicode range:
0x600-0x6FF
0x750-0x77F
Presentation:0xFB50 - FDFF
--------------------------- **/
#define IsArabicUnicodeCode(uUin) (((uUin >= 0x600) && (uUin <= 0x6FF)) || ((uUin >= 0x750) && (uUin <= 0x77F)))
#define IsSpecialChar(uCurUni,uUin) ((uCurUni==0x644)&&((uUin==0x622)||(uUin==0x623)||(uUin==0x625)||(uUin == 0x627)))
#define SpecialCharInex(uUin) ((uUin==0x622)?0:((uUin==0x623)?1:((uUin==0x625)?2:(uUin==0x627)?3:3)))
#define IsFrontCennectChar(uLastUni) ((uLastUni==0x626)||(uLastUni==0x628)||((uLastUni>=0x62A)&&(uLastUni<=0x62E))||\
((uLastUni>=0x633)&&(uLastUni<=0x63A))||((uLastUni>=0x640)&&(uLastUni<=0x648))||(uLastUni==0x64A))
#define IsBackCennectChar(uNextUni) (((uNextUni>=0x622)&&(uNextUni<=0x63A))||((uNextUni>=0x640)&&(uNextUni<=0x64A)))
#define IsSpaceChar(uUin) ((/*(uUin==0x00)||*/(uUin==0x0A) || (uUin==0x0D) || (uUin==0x20)))
#define IsCennectChar(uCurUni) ((uCurUni>=0x621)&&(uCurUni<=0x64A))
#define ArabicListIndex(uUin) (uUin - 0x621)
bool gutCheckArabicReverse(uint16* u16Src,uint8 u8StrLen){
uint8 u8i;
bool boRet;
boRet = False;
for(u8i = 0;(u8i < u8StrLen) && (u16Src[u8i] != 0) && (u8i < 32);u8i++) {
if(IsArabicUnicodeCode(u16Src[u8i])) {
boRet = True;
break;
}
}
return boRet;
}
bool gutArabicSrcStrCovPrintStr(uint16* u16Src,uint8 u8StrLen) {
uint16 u16CopyStr[32];
uint8 u8i,u8j,u8k,u8CurId,u8Start,u8LastArabicId;
uint16 u16Unicode,u16LastUni,u16NextUni,u16CovUni;
bool boIsFront,boIsBack;
uint16* arbicSpecs;
uint16* ArbicPosition;
arbicSpecs = (uint16*)&(arabic_specs[0]);
ArbicPosition = (uint16*)&(Arbic_Position[0]);
for(u8i = 0;(u8i < u8StrLen) && (u16Src[u8i] != 0) && (u8i < 31);u8i++) {
u16Unicode = u16Src[u8i];
/* Reverse */
if(IsArabicUnicodeCode(u16Unicode)) {
u8Start = u8i;
u8LastArabicId = u8i;
u8j = u8Start + 1;
while(u8j < 31) {
u16Unicode = u16Src[u8j];
if(IsArabicUnicodeCode(u16Unicode)) {
u8LastArabicId = u8j;
} else {
if(!IsSpaceChar(u16Unicode)) {
break;
}
}
u8j++;
}
/* Reverse Dispary */
for(u8k=0;u8j < 31 && u8j > u8Start;u8j--,u8k++) {
u16CopyStr[u8j-1] = u16Src[u8i+(u8k)];
}
u8j = 0;
while(u8j < (u8LastArabicId - u8Start + 1)) {
u16Unicode = u16Src[(u8Start + u8j)];
if(IsCennectChar(u16Unicode)) {
if((u8Start+u8j) > 0) {
u16LastUni = u16Src[(u8Start+u8j) - 1];
} else {
u16LastUni = 0xFFFF;
}
if((u8Start+u8j) < 30) {
u16NextUni = u16Src[(u8Start+u8j) + 1];
} else {
u16NextUni = 0xFFFF;
}
boIsBack = False;
boIsFront = False;
if(IsBackCennectChar(u16NextUni)) {
boIsBack = True;
}
if(IsFrontCennectChar(u16LastUni)) {
boIsFront = True;
}
if(IsSpecialChar(u16Unicode,u16NextUni)) {
u8CurId = SpecialCharInex(u16NextUni);
u16CovUni = *(arbicSpecs+(u8CurId*2)+boIsFront);
u16CopyStr[u8LastArabicId - u8j] = u16CovUni;
u8j++;
u16CopyStr[u8LastArabicId - u8j] = 0xFFFF;
} else if((boIsFront == True) && (boIsBack == True)) {
u8CurId = ArabicListIndex(u16Unicode);
u16CovUni = *(ArbicPosition+(u8CurId*4+2));
u16CopyStr[u8LastArabicId - u8j] = u16CovUni;
} else if(boIsFront == True) {
u8CurId = ArabicListIndex(u16Unicode);
u16CovUni = *(ArbicPosition+(u8CurId*4+0));
u16CopyStr[u8LastArabicId - u8j] = u16CovUni;
} else if(boIsBack == True) {
u8CurId = ArabicListIndex(u16Unicode);
u16CovUni = *(ArbicPosition+(u8CurId*4+1));
u16CopyStr[u8LastArabicId - u8j] = u16CovUni;
} else {
u8CurId = ArabicListIndex(u16Unicode);
u16CovUni = *(ArbicPosition+(u8CurId*4+3));
u16CopyStr[u8LastArabicId - u8j] = u16CovUni;
}
} else {
u16CopyStr[u8LastArabicId - u8j] = u16Unicode;
}
if(u8j == 31) {
break;
}
u8j++;
}
u8i = u8LastArabicId;
} else {
/* No change */
u16CopyStr[u8i] = u16Src[u8i];
}
}
u16CopyStr[u8i] = 0;
for(u8i = 0,u8j=0;(u8i < u8StrLen) && (u16CopyStr[u8i] != 0) && (u8i < 31);u8i++) {
if(u16CopyStr[u8i] != 0xFFFF){
u16Src[u8j] = u16CopyStr[u8i];
u8j++;
}
}
u16Src[u8j] = 0;
}
标签:u16CopyStr,uUin,LCD,uint16,&&,字符串,嵌入式,u8j,u8i 来源: https://www.cnblogs.com/li-hw/p/16420955.html