2011-03-24 74 views
2

我需要在打印之前知道文本的方向。如何識別C++中的RTL字符串

我正在使用Unicode字符。

我該如何在C++中做到這一點?

+0

我相信大關RTL是U + 200F ... Unicode是有點廣闊。你使用的是什麼UTF編碼,什麼平臺,什麼語言和區域設置? – AJG85 2011-03-24 19:01:32

回答

5

如果您不想使用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似乎是如何工作的。

5

您可以使用ICU庫,該庫有一個功能(ubidi_getDirectionubidi_getBaseDirection)。

通過重新編譯數據庫(通常大約15MB),可以減少ICU的大小,使其僅包含項目所需的轉換器/本地化器。

該部分減小ICU數據的大小:轉換表的網站http://userguide.icu-project.org/icudata包含有關如何縮小數據庫大小的信息。如果只需要支持最常見的編碼(US-ASCII,ISO-8859-1,UTF-7/8/16/32,SCSU,BOCU-1,CESU-8),則數據庫不會是無論如何。

+0

好的,getBaseDirection是他需要的+1 :) – ybungalobill 2011-03-24 19:13:16

+0

謝謝,但它的大小約爲16MB。 我發現,微軟開始提供BIDI支持像10年前的一個DLL: 「的Uniscribe」和蘋果有它自己的並行「ATSUI」。 在它們之上是否有任何C++ BIDI跨平臺適配器? 謝謝。 – kambi 2011-03-26 18:00:12

+0

我不知道,但關於ICU,這些16MB中的大部分是由默認包含編碼/解碼錶等幾乎所有編碼的data-dll引起的。它可以很容易地縮小規模。請參閱http://userguide.icu-project.org/icudata,「減少ICU數據的大小:轉換表」部分 – smerlin 2011-03-27 19:01:27

-1

如果您使用的是Windows GDI,看起來GetFontLanguageInfo(HDC)會返回一個DWORD;如果設置了GCP_REORDER,則該語言需要重新排序才能顯示,例如希伯來語或阿拉伯語。

+0

我並不是故意諷刺,但我可以指出,localhost的url並不普遍所有在互聯網上有用的。 – Arafangion 2012-10-11 07:01:43

1

從波阿斯的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; 
}