ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

嵌入式中 动态阿拉伯语字符串 转换 LCD显示字符串【感谢建国雄心】

2022-06-28 20:32:58  阅读:111  来源: 互联网

标签:u16CopyStr uUin LCD uint16 && 字符串 嵌入式 u8j u8i


本文参考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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有