如何识别C ++中的RTL字符串

时间:2011-03-24 18:46:22

标签: c++ unicode right-to-left bidi

我需要在打印前知道文字的方向。

我正在使用Unicode字符。

我怎样才能在C ++中做到这一点?

4 个答案:

答案 0 :(得分:6)

如果您不想使用ICU,您可以随时手动解析unicode database(例如,使用python脚本)。它是一个以分号分隔的文本文件,每行代表一个字符代码点。查找每行中的第五条记录 - 这是字符类。如果是RAL,则表示您有RTL字符,而'L'是LTR字符。其他类是弱或中性类型(如数字),我猜你想忽略。使用该信息,您可以生成所有RTL字符的查找表,然后在C ++代码中使用它。如果您真的关心代码大小,可以通过使用范围(而不是每个字符的条目)来最小化查找表在代码中占用的大小,因为大多数字符都是BiDi类的块。

现在,定义一个名为GetCharDirection(wchar_t ch)的函数,它通过检查查找表来返回枚举值(例如:Dir_LTRDir_RTLDir_Neutral)。

现在你可以定义一个函数GetStringDirection(const wchar_t*),它贯穿字符串中的所有字符,直到遇到一个非Dir_Neutral的字符。字符串中的第一个非中性字符应设置该字符串的基本方向。或者至少这就是ICU的工作方式。

答案 1 :(得分:5)

您可以使用ICU库,该库具有相应的功能(ubidi_getDirection ubidi_getBaseDirection)。

通过重新编译数据库(通常大约15MB)可以减少ICU的大小,只包括项目所需的转换器/本地。

网站http://userguide.icu-project.org/icudata减少ICU数据大小:转换表部分包含有关如何减小数据库大小的信息。

如果只需要支持最常见的编码(US-ASCII,ISO-8859-1,UTF-7/8/16/32,SCSU,BOCU-1,CESU-8),则不需要数据库反正。

答案 2 :(得分:2)

来自Boaz Yaniv之前说过,也许这样的事情比解析整个文件更容易,更快:

int aft_isrtl(int c){
  if (
    (c==0x05BE)||(c==0x05C0)||(c==0x05C3)||(c==0x05C6)||
    ((c>=0x05D0)&&(c<=0x05F4))||
    (c==0x0608)||(c==0x060B)||(c==0x060D)||
    ((c>=0x061B)&&(c<=0x064A))||
    ((c>=0x066D)&&(c<=0x066F))||
    ((c>=0x0671)&&(c<=0x06D5))||
    ((c>=0x06E5)&&(c<=0x06E6))||
    ((c>=0x06EE)&&(c<=0x06EF))||
    ((c>=0x06FA)&&(c<=0x0710))||
    ((c>=0x0712)&&(c<=0x072F))||
    ((c>=0x074D)&&(c<=0x07A5))||
    ((c>=0x07B1)&&(c<=0x07EA))||
    ((c>=0x07F4)&&(c<=0x07F5))||
    ((c>=0x07FA)&&(c<=0x0815))||
    (c==0x081A)||(c==0x0824)||(c==0x0828)||
    ((c>=0x0830)&&(c<=0x0858))||
    ((c>=0x085E)&&(c<=0x08AC))||
    (c==0x200F)||(c==0xFB1D)||
    ((c>=0xFB1F)&&(c<=0xFB28))||
    ((c>=0xFB2A)&&(c<=0xFD3D))||
    ((c>=0xFD50)&&(c<=0xFDFC))||
    ((c>=0xFE70)&&(c<=0xFEFC))||
    ((c>=0x10800)&&(c<=0x1091B))||
    ((c>=0x10920)&&(c<=0x10A00))||
    ((c>=0x10A10)&&(c<=0x10A33))||
    ((c>=0x10A40)&&(c<=0x10B35))||
    ((c>=0x10B40)&&(c<=0x10C48))||
    ((c>=0x1EE00)&&(c<=0x1EEBB))
  ) return 1;
  return 0;
}

答案 3 :(得分:-1)

如果您使用的是Windows GDI,GetFontLanguageInfo(HDC)似乎会返回一个DWORD;如果设置了GCP_REORDER,则语言需要重新排序才能显示,例如希伯来语或阿拉伯语。