• 嵌入式中 动态阿拉伯语字符串 转换 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;
    }


     

  • 相关阅读:
    五子棋游戏禁手算法的改进
    基于Python的旅游景点推荐系统设计与实现(源码+数据库+讲解)
    PHP旅游管理系统Dreamweaver开发mysql数据库web结构php编程计算机网页
    找准方向选CRM客户管理系统!2023年排行榜推荐
    如何理解 Python 装饰器
    软件代码签名证书怎么申请
    职场IT老鸟的几点小习惯
    图像处理之图像统计特性
    金融信创黄金三年:小程序生态+跨端技术框架构建
    三台centos7部署redis6.2版本集群
  • 原文地址:https://www.cnblogs.com/li-hw/p/16420955.html