当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]嵌入式系统多语言文本解决方案

嵌入式系统开发中,某些产品可能会需要跨区域销售,因此,通常会有多语言的需求。对于这一类多语言需求的解决,在嵌入式产品中有其特殊的地方。以下,给出一种可能的解决方案。

该方案的核心思想是为所有文本建立索引,通过索引可以得到特定语言的文字编码,随后通过该编码获得字库资源,并进行输出。在这过程中,唯一需要注意的是对于特殊的某些语言,如阿拉伯语等的处理。(阿拉伯语字符在连写时,其形状会发生变化。)

1. 字库的建立:

文本最终都将输出给用户,因此,必须为文本内容指定字库。本方案中采用UNICODE编码字库。字库文件采用二进制存储,按UNICODE编码顺序排列存储点阵数据,点阵大小为24*24。

2. 文本资源文件:

文本资源文件描述了特定语言的文本内容,以及相关的字符编码。例如对于Chinese.cfg文件来说,就保留了一个索引为1的文本,该文本内容为“确认”;相应对于English.cfg文件来说,必然会同样有一个索引为1的文本,该文本内容为“CONfirm”。通过对所有的文本建立索引并生成文本资源文件,就为最终的解决扫清了障碍。

文本资源文件采用二进制存储。文件头部16个字节为描述性信息,之后是文本映射表,紧跟映射表之后为文本的实际Unicode编码。

3. 对文本资源文件进行描述的数据结构

  typedef STruct _txtres_fileheader {

  LONG lFileType; //文件类型,0x2E434647=‘.CFG‘

  LONG lVersionNum; //适用版本,0x56313032=‘V102‘

  LONG lMapOffset; //偏移量,文件头到文本映射区的偏移量

  LONG lDataOffset; //偏移量,文件头到文本数据区的偏移量

  } APPteXT_FILEHEADER;

4. 文本映射表结构

  typedef struct _txtres_txtmap {

  WORD wTextIndes; //当前文本的索引值

  WORD wTextSize; //当前文本的Unicode编码所占用的字节数

  LONG lUnicodeOffset; //从文件头到当前文本Unicode编码存储位置的偏移量

  } TXTRES_TXTMAP;

5. 特殊语言(阿拉伯语等)的解决

特殊语言在连写时可能发生变化,因此采用固定字库可能无法解决该问题。针对这种状况可以直接新增一个自定义字库。以阿拉伯语为例,该字库的处理过程如下:

a. 首先将阿拉伯的文本内容按预定格式(例如24*24)在windows系统上显示输出,并将内容保存为图片格式。此时图片中便为连写内容。

b. 随后,对图片进行分割。如按照24*24进行分割便可得到特定的24*24大小的字库内容。

c. 最后,将原先的UNICODE编码转为按照之前生成的字库来编码。

d. 之后在程序代码中就可利用自定义字库与自定义编码来显示阿拉伯语。

最后附上部分示例代码。

  //定义文本配置文件路径

  #define TXT_FILE_ENGLISH "config/English.cfg"

  #define TXT_FILE_CHINASIM "config/ChinaSim.cfg"

  #define TXT_FILE_CHINATRA "config/ChinaTra.cfg"

  #define TXT_FILE_KOREAN "config/Korean.cfg"

  #define TXT_FILE_JAPANESE "config/Japanese.cfg"

  #define TXT_FILE_SPANISH "config/Spanish.cfg"

  #define TXT_FILE_RUSSIAN "config/Russian.cfg"

  #define TXT_FILE_THAI "config/Thai.cfg"

  #define TXT_FILE_GERMAN "config/German.cfg"

  #define TXT_FILE_FRANCE "config/France.cfg"

  #define TXT_FILE_ITALY "config/Italy.cfg"

  #define TXT_FILE_ARABIA "config/Arabia.cfg"

  #define TXT_FILE_PORTUGAL "config/Portugal.cfg"

  #define TXT_FILE_HINDI "config/Hindi.cfg"

  #define TXT_FILE_TURKISH "config/Turkish.cfg"[!--empirenews.page--]

  #define TXT_FILE_VIETNAM "config/Vietnam.cfg"

  #define TXT_FILE_SWIDISH "config/Swedish.cfg"

  #define TXT_FILE_POLISH "config/Polish.cfg"

  //根据文本索引及文本语言,读取相应的文本配置文件,以得到该文本,成功返回有效指针

  GUISTRING * GetTextResource(LONG lIndex, LONG lLanguage)

  {

  GUISTRING * pTxt;

  APPTEXT_FILEHEADER fh;

  APPTEXT_MAPPING map;

  STRING strFile;

  WORD * pBuf;

  int fd, iOff;

  //确定要读取的配置文件

  switch (lLanguage)

  {

  case TXT_LANG_ENGLISH:

  strFile = TXT_FILE_ENGLISH;

  break;

  case TXT_LANG_CHINASIM:

  strFile = TXT_FILE_CHINASIM;

  break;

  case TXT_LANG_CHINATRA:

  strFile = TXT_FILE_CHINATRA;

  break;

  case TXT_LANG_KOREAN:

  strFile = TXT_FILE_KOREAN;

  break;

  case TXT_LANG_JAPANESE:

  strFile = TXT_FILE_JAPANESE;

  break;

  case TXT_LANG_SPANISH:

  strFile = TXT_FILE_SPANISH;

  break;

  case TXT_LANG_RUSSIAN:

  strFile = TXT_FILE_RUSSIAN;

  break;

  case TXT_LANG_THAI:

  strFile = TXT_FILE_THAI;

  break;

  case TXT_LANG_GERMAN:

  strFile = TXT_FILE_GERMAN;

  break;

  case TXT_LANG_FRANCE:

  strFile = TXT_FILE_FRANCE;

  break;

  case TXT_LANG_ITALY:

  strFile = TXT_FILE_ITALY;

  break;

  case TXT_LANG_ARABIA:

  strFile = TXT_FILE_ARABIA;

  break;

  case TXT_LANG_PORTUGAL:

  strFile = TXT_FILE_PORTUGAL;

  break;

  case TXT_LANG_HINDI:

  strFile = TXT_FILE_HINDI;

  break;

  case TXT_LANG_TURKISH:

  strFile = TXT_FILE_TURKISH;

  break;

  case TXT_LANG_VIETNAM:

  strFile = TXT_FILE_VIETNAM;

  break;

  case TXT_LANG_SWIDISH:

  strFile = TXT_FILE_SWIDISH;

  break;

  case TXT_LANG_POLISH:[!--empirenews.page--]

  strFile = TXT_FILE_POLISH;

  break;

  default:

  return NULL;

  }

  //打开配置文件并检查其格式

  if ((fd = open(strFile, O_RDONLY)) == -1)

  {

  return NULL;

  }

  if (read(fd, &fh, 16) != 16)

  {

  close(fd);

  return NULL;

  }

  if (fh.lFileType != 0x4746432E || fh.lVersionNum != 0x32303156)

  {

  close(fd);

  return NULL;

  }

  //在文本映射区内查找匹配的文本索引

  for (iOff = fh.lMapOffset; iOff < fh.lDataOffset; iOff += 8)

  {

  if (read(fd, &map, 8) != 8)

  {

  close(fd);

  return NULL;

  }

  if (map.wTextIndex == lIndex)

  {

  break;

  }

  }

  if (iOff >= fh.lDataOffset)

  {

  close(fd);

  return NULL;

  }

  //根据找到的文本映射来读取文本内容

  if (!(pBuf = GuiMemAlloc(map.wTextSize + 2)))

  {

  close(fd);

  return NULL;

  }

  lseek(fd, fh.lDataOffset + map.lTextOffset, SEEK_SET);

  if (read(fd, pBuf, map.wTextSize) != map.wTextSize)

  {

  GuiMemFree(pBuf);

  close(fd);

  return NULL;

  }

  pBuf[map.wTextSize >> 1] = 0;

  //建立字符串对象

  pTxt = CreateStringDirect(pBuf);

  GuiMemFree(pBuf);

  close(fd);

  return pTxt;

  }

  //定义与字符串相关的数据结构

  #ifndef GUI_STRING_STRUCT

  typedef struct _string

  {

  WORD wWidth; //字符串宽度,字符串输出时的总点阵宽度

  WORD wLength; //字符串长度,不包括‘‘

  WORD * pContent; //字符串内容,以‘‘结尾

  } GUISTRING;

  //结束与字符串相关的数据结构的定义

  #define GUI_STRING_STRUCT

  #endif

  /***[!--empirenews.page--]

  * 功能:

  根据指定的信息直接建立字符串,函数返回字符串指针

  * 参数:

  1.WORD * pContent: 字符串内容

  * 返回:

  成功返回字符串指针

  失败返回NULL

  * 备注:

  ***/

  GUISTRING * CreateStringDirect(WORD * pContent)

  {

  GUISTRING * pStr;

  //尝试为字符串分配内存

  if (!(pStr = GuiMemAlloc(sizeof(GUISTRING))))

  {

  PRINT_INF(CreateStringDirect Err0!);

  return NULL;

  }

  //字符串内容为空,建立一个空字符串对象

  if (!pContent)

  {

  pStr->wWidth = 0;

  pStr->wLength = 0;

  pStr->pContent = NULL;

  return pStr;

  }

  //统计字符串长度

  pStr->wLength = 0;

  pStr->pContent = pContent;

  while (*pStr->pContent++)

  {

  pStr->wLength++;

  }

  //尝试为字符串内容分配内存

  if (!(pStr->pContent = GuiMemAlloc((pStr->wLength + 1) << 1)))

  {

  GuiMemFree(pStr);

  PRINT_INF(CreateStringDirect Err1!);

  return NULL;

  }

  //写入字符串内容

  memcpy(pStr->pContent, pContent, (pStr->wLength + 1) << 1);

  //计算字符串宽度

  if (_StringObjectFill(pStr))

  {

  GuiMemFree(pStr->pContent);

  GuiMemFree(pStr);

  PRINT_INF(CreateStringDirect Err2!);

  return NULL;

  }

  return pStr;

  }

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭