歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> Linux文化 >> Linux 國際化本地化和中文化(三)

Linux 國際化本地化和中文化(三)

日期:2017/2/27 12:19:15   编辑:Linux文化

--------------------------------------------------------------------------
國際化、本地化和中文化 國際化、本地化和多語言化的概念 中文化 X11 國際化的歷史和級別 國際化標准組織 國際化的意義

Locale Locale 的概念 在X中使用Locale 文化習俗的差別

X 窗口系統的國際化 顯示的國際化 字符集和編碼 多字節字符(Multibyte)和寬字符(WideChar)的使用 Unicode 字體(Font)和字體集(FontSet) 信息的國際化 輸入的國際化 打印的國際化 客戶程序間通訊的國際化

開發符合國際化標准的軟件 開發國際化軟件 使非國際化軟件國際化

目前中文化中存在的問題 編碼動態切換的問題 中文編碼自動識別問題 Linux上的中文平台到國際化的過渡

附錄 寬字符處理函數函數與普通函數對照表 X 窗口系統下支持中文的函數庫 支持多語言的典型軟件 支持Unicode的軟件 --------------------------------------------------------------------------

三 X 窗口系統的國際化

在 X 窗口系統上的國際化, 特別是中文化, 主要體現在顯示,輸入和打印三個方面.

1. 顯示的國際化

1. 字符集和編碼

在Linux上經常使用的字符集是ISO 8859系列的字符集. 它包含了10個 多語 言的單字節編碼字符集. 它們分別是, 字符集 涵蓋語言 拉丁一字符集, 包含絕大多數的歐洲語言, 例如French(fr), Spanish (es), Catalan (ca), Basque (eu), Portuguese (pt), Italian (it), Albanian (sq), Rhaeto-Romanic (rm), Dutch (nl), ISO 8859-1(Latin1) German (de), Danish (da), Swedish (sv), Norwegian (no), Finnish (fi), Faroese (fo), Icelandic (is), Irish (ga), Scottish (gd), English (en), Afrikaans (af) 和 Swahili (sw). 影響了 美洲, 澳洲和非洲. 拉丁二字符集, 包含了中歐和東歐的語 ISO 8859-2(Latin2) 言:Czech (cs), Hungarian (hu), Polish (pl), Romanian (ro), Croatian (hr), Slovak (sk), Slovenian (sl), Sorbian.

ISO 8859-3(Latin3) 拉丁三字符集, 包括: Esperanto (eo) and Maltese (mt)

拉丁四字符集, 包括: Estonian (et), 巴 ISO 8859-4(Latin4) 爾地克 Latvian (lv) 和 Lithuanian (lt), Greenlandic (kl) , Lappish. Bulgarian (bg), Byelorussian (be), ISO 8859-5(西裡爾語) Macedonian (mk), Russian (ru), Serbian (sr) ISO 8859-6(阿拉伯語) 阿拉伯語(ar) ISO 8859-7(希臘語) 希臘語(el) ISO 8859-8(希伯來語) Hebrew (iw) 和Yiddish (ji)

ISO 8859-9(Latin5) 重排了Latin1, 用土耳其語的幾個字母做了 替換

ISO 8859-9(Latin6) 重排了Latin4, 去掉了某些符號, 增加了 Inuit等 ISO 8859-11(泰國語) 泰國語(th)

ISO 8859-12 Celtic

ISO 8859-13(Latin7) Baltic Rim 和 Lativian(lv) ISO 8859-14(Latin8) Gaelic 和 Welsh (cy) ISO 8859-15(Latin9) Latin1的變種, 修改了某些字母

雙字節字符集主要包含中文,日文和韓文. 它由前導字節(Lead Byte) 和尾 部字節(Trail Byte)構成, 由於一個字符采用了兩個字節, 在軟件的 國際 化方面又增加了一些麻煩, 比如在顯示上, 光標的位置不能位於漢字 之間, 刪除和移動時必須是整字操作等, 在輸入上, 一般需要預編輯服務器 才能 輸入漢字. 下表列出了中日韓語言編碼的有關信息:

語 前導字節范 言 字符集 代碼頁 圍 尾部字節范圍 簡 GB2312-1980 CP936 0xA1-0xF7 0xA1-0xFE 體 中 文 GBK 無 0x81-0xFE 0x40-0x7E, 0x80-0xFE 中 文 繁 BIG-5 CP950 0x81-0xFE 0x40-0x7E, 0xA1-0xFE 體 日 0x81-0x9F, 文 Shift-JIS CP932 0xE0-0xFC 0x40-0xFC(0x7F除外) KSC-5601-1987 CP949 0x81-0xFE 0x41-0x5A,0x61-0x7A,0x81-0xFE 0x84-0xD3 韓 0xD8 0x41-0x7E 文 KSC-5601-1992 CP1361 0xD90-0xDE 0x81-0xFE 0xE0-0xF9 0x31-0x7E 0x41,0xFE

最近, 信息產業部和國家質量技術監督局聯合發布了兩項新的中文信息 處 理基礎性國家標准,為解決偏、生漢字的輸入提供了方案。其中GB18030- 2000《信息技術和信息交換用漢字編碼字符集、基本集的擴充》,為強制性 國家標准. 它收錄了2.7萬多個漢字,總編碼空間超過150萬個碼位,為徹底 解決郵政、戶政、金融、 地理信息系統等迫切需要的人名、地名用字問題 提供了解決方案,也為漢字研究、古籍整理等領域提供了統一的信息平台基 礎。 這項標准還同時收錄了藏文、蒙文、維吾爾文等主要的少數民族文字. 字符 集編碼范圍是:

字節數 編碼空間 碼位數目 單字節 0x00-0x80 129

雙字節 第一字節:0x81-0xFE 23940 第二字節:0x40-0x7E,0x80-0xFE

四字節 四字節范圍分別是: 1587600 0x80-0xFE,0x30-0x39,0x81-0xFE,0x30-0x39

香港特別行政區也對Big5編碼提出了"香港增補字符集", 其目的,是 收納 香港特區政府及市民在中文電子通訊中有需要使用的字符,來補充目前 大 五碼和ISO10646編碼標准內並未包含的字符,以作為一個通用的中文界面, 方便大家能准確地以中文進行電子通訊。香港增補字符集有兩套編碼方案, 一套適用於大五碼系統,另一套適用於ISO10646平台。香港增補字符集的大 五碼版本,實際上是政府通用字庫的增訂版。ISO10646國際編碼標准目前並 未包含香港增補字符集內的所有字符。目前尚未收納在ISO10646內的香港增 補字符集字符,均已提交國際標准化組織管轄下的表意文字小組,以考慮是 否納入ISO10646日後的新增版本內.

上述標准和草案應該是以後的中文Linux所應該遵循的.

2. 多字節字符(Multibyte)和寬字符(WideChar)的使用

我們平時見到的以文本方式存在的字符都是多字節字符, 它主要用於 文件 存儲和網絡上的以流(Stream)的方式傳輸. 一個GB編碼的漢字需要兩個 字 節. 多字節字符的缺點是在中文處理上不方便, 比如漢字的刪除和光標的 移動都會有半漢字問題. 為了文本處理的方便, 在內部操作上通常是把漢字 與英文的混和字符串先轉換成等寬度的字符串, 即寬字符, 為軟件的內部處 理 提供方便.

glibc2.1.x中多字節字符串和寬字符串的轉換有時有問題. 在X下還可以 使 用另外一種方式完成轉換, 即使用XmbTextListToTextProperty()和 XwcTextPropertyToTextList() 聯合完成轉換.

3. Unicode

目前所使用的Unicode 是一種16位字寬的字符編碼, 它由非贏利的計算機 組織Unicode研討會維護和改進. 它起源於Xerox和Apple之間的合作研究. 幾 個公司組成了一個非正式的論壇, 接著IBM, Microsoft等公司迅速加入. Unicode研討會在1990年發表了Unicode標准版本1, 同時國際標准化組織完 成 了一種類似的編碼----ISO 10646. 因為沒有必要存在兩套標准, 所以 Unicode 研討會和國際標准化組織在1991到1992合二為一. 1994年, 中國和 日本開始對 基於ISO10646上的國家標准進行工作. 現在, Unicode 開始用 在許多產品中.

Unicode包含了當今計算機領域中廣泛使用的所由字符, 如世界上大部分 的 書面語言, 印刷字符, 數字和技術符號, 地理圖形和標點符號. 由於 Unicode 的一致性, 它在大多數情況下都可能簡化軟件的國際化過程. 它取 消了處理 多種代碼頁的必要, 並且由於是16位編碼, 因此由雙字節字符集 所引起的額外 處理也不必要了.

但是, Unicode作為一種編碼也有它的缺陷, 比如編碼的位置與排序無關, 所以使軟件支持Unicode僅僅是國際化的第一步, 實際情況中還需要與語言 相關 的信息和規則. 所以Unicode一般作為程序的內部處理編碼, 必須提供 與其它 編碼的雙向轉換表.

最後需要說明的是, 雖然使用Unicode會使普通的英文文本大兩倍, 但是 使 用Unicode的整個系統卻不會增加太大, 因為系統存放的文件大部分是二進 制 文件格式, 同時, 使用針對Unicode的壓縮方式, 可以把文件壓縮成和使 用對應 的8位正文一樣大小.

4. 字體(Font)和字體集(FontSet)

在X窗口系統下使用的字體都必須在X服務器中注冊X邏輯字體描述(X Logical Font Description)名. 它包括了字體的許多信息, 例如以下為西 文字體和中文 字體的兩個例子.

1. -adobe-times-medium-r-normal--14-140-75-75-p-74-iso8859-1 2. -tlc-song-medium-r-normal--24-240-75-75-c-240-gbk-0

為了方便使用, 用戶還可以給每一個字體加一個或多個別名, 別名文件 fonts.alias 放在字體目錄下, 可以手工編輯. 當字體目錄變更或別名變更 後, 必須使用命令 "xset fp rehash"或重新啟動X才起作用.

X 字體也可以通過字體服務器(Font Server)加載. 這對於本地不放字體 的 系統或X終端特別有用. 加載的協議可以是TCP或DECNET.

X 窗口系統的字體在X Server中之存在一份, 當所由軟件都不使用它時, 字 體的內存自動施放.

字體中包含了制造商名, 字體類型, 權重, 字體大小, 字符集等信息. 它們 也 可以縮寫, 省去的部分用星號代替, 比如對上面的中文字體, 可以縮寫 為:

-*-song-*-24-*-gbk-0

在實際應用中, 字符串往往是中文和英文的混和字符串, 所以必須使用兩種 字體來繪出該字符串, 這種指定兩種或兩種以上的字體的描述就是字體集. 字體 集一般的格式是把多種字體用逗號隔開, 比如, 指定下列字體集:

"-adobe-helvetica-medium-r-normal--14-*-*-*-*-*-iso8859-*,\ -tlc-song-medium-r-normal--14-*-*-*-*-*-gbk-0"

令人遺憾的是, 中文的GB編碼和Big5編碼有重疊區域, 不能區分開來, 所以 字體集並不能同時指定GB和Big5的字體.

字體集的具體載入受到Locale的影響.

在許多已經國際化的軟件和圖形庫中, 一般通過資源文件讓用戶指定字體 集, 比如gtk的簡體中文資源文件為/etc/gtk/gtkrc.zh_CN, qt-1.44(國際 化的)的 資源文件是 ~/.qti18nrc 等等.

2. 信息的國際化

信息(Message)國際化是軟件國際化中比較重要的一環, 如果使軟件可以 支持多 種語言, 在設計時就應當考慮到信息的國際化問題. 現在的絕大多數 軟件使用 GNU的gettext作為基本工具. 信息國際化的基本步驟是: o 在軟件初始化時設置使用setlocale()設置Locale o 使用gettext宏定義, 使程序看上去比較方便: o 指定信息的位置: o 指定翻譯信息: _("Some Strings"); o 在軟件完成後,使用 xgettext 提取信息並翻譯 o 使用msgfmt把信息文件轉換為.mo文件, 安裝到locale目錄下

/* file this_app.c */ #include #include #define _(String) gettext(String) #define N_(String) gettext(String) #define __(String) (String)

int main(){ //由環境變量決定locale setlocale(LC_ALL, "");

//設置message的位置和文件名 bindtextdomain("this_app", "/usr/share/locale"); textdomain("this_app");

printf(_("Some String")); }

至此, 本程序的國際化過程已完成. 編譯並聯接成可執行文件this_app.

gcc -o this_app this_app.c

下面是本地化的過程.

o 提取要翻譯的信息: xgettext -a -o this_app.po this_app.c o 翻譯信息

在文件this_app.po 中含有"Some String":

msgid "Some String" msgstr ""

翻譯成:

msgid "Some String" msgstr "一些字符串"

o 格式化信息文件: msgfmt -o this_app.mo this_app.po o 拷貝信息文件到locale的目錄下, 比如對於中文zh_CN, cp this_app.mo /usr/share/locale/zh_CN/LC_MESSAGES o 執行文件: LC_ALL=zh_CN ./this_app

3. 輸入的國際化

在X窗口系統下輸入主要有三種方式:

1. 單此擊鍵輸入單字符 2. 兩個或多個組合鍵輸入單字符 3. 除鍵輸入外, 還需要轉換服務器

其中前兩種用於輸入西文字符, 比如對於歐洲語言的特殊字符的輸入, 通常采用 重映射鍵盤的方法. 或者使用"加速鍵"的方法輸入, 加速鍵是鍵盤 上的特殊鍵, 按下後不會使光標向後移動.

在Linux下, 使用軟件xkeycaps可以把鍵盤重新映射並且保存整個鍵盤 在映射後 的對照表, 使用命令xmodmap可以加載映射表.

對於中文輸入, 主要使用第三種輸入方式. 針對各種語言的綜合考慮, X 窗口系 統在輸入上定義了下列區域:

1. 預編輯區域(Preedit Area), 用於顯示輸入的過程, 當用戶輸入 字符時, 應立即顯示在該區域 2. 狀態區域(Status Area), 用於顯示輸入狀態, 對中文來說, 用於顯示輸入 方法, 全角/半角狀態, 中文/西文標點符號狀態. 3. 輔助區域(Auxiliary Area), 顯示可供選擇的列表, 又稱選擇 區域, 它由 輸入服務器控制.

根據預編輯區域和狀態區域的不同組合, X 窗口系統共定義了四種輸入 的風格 (Input Style):

1. Root風格: 預編輯區域和選擇區域都在應用軟件之外, 它們都是 由輸入服 務器完成的, 輸入服務器所顯示的界面是根窗口的子 窗口. 如類似"中文之 星"的獨立的輸入條模式. 2. OffTheSpot風格: 預編輯區域和選擇區域在應用軟件之內, 通常 是在窗口 下方的某個固定區域內. 如XEmacs的缺省輸入模式. 3. OverTheSpot風格: 預編輯區域在當前的輸入位置, 狀態區域 在應用程序的 某一固定區域. 它通常又稱為光標跟隨模式, 類似 於Windows下的智能ABC 輸入方法 4. OnTheSpot風格: 預編輯區域和選擇區域都在應用軟件之內, 內容是又輸入 服務器發送的, 應用程序負責顯示.

對中文輸入來說, 最好的風格是(3),(4),(1). 對大部分中文輸入方法, 必須彈出 輔助區域, 供用戶選擇, 只有少數的中文輸入方法, 如五筆字型, 比較適合(4). 對於狀態區域, 中文輸入多數選用在Root風格的窗口的某個 位置或使用專用的控 制條. 在MS Windows下比較常用的光標跟隨模式, 可以 用(3),(4)來實現. 鑒於 Linux下有的用戶把X Window設置成為虛屏模式, 選 擇上述的任何一種模式都不 盡滿意.

對應用軟件來說, 最簡單的輸入接口是Root風格, 它把顯示部分交給 輸入服務器 去做. 編寫軟件時所用的代碼量少, 是對軟件初步使用國際化 標准的最佳選擇. 從方便用戶的角度來看, 應用軟件, 特別是高層的庫函數 應該同時支持四種輸入 風格. 令人遺憾的是, 一般軟件僅支持兩到三種輸入 風格. 所以在現在的輸入服 務器(IM Server)也很少支持四種風格, 這似乎 成了雞和蛋的問題.

下面列出幾種常用軟件和圖形庫的XIM支持情況:

NetscapeRoot,OffTheSpot,OverTheSpot Java Root,OnTheSpot Qt Root,OverTheSpot gtk+ Root,OverTheSpot rxvt Root,OffTheSpot,OverTheSpot

中文輸入需要客戶軟件和服務器軟件的的密切配合, 它們之間是通過 XIM(X Input Method)協議來通訊的. 輸入服務器首先起動, 在X Server裡 注冊自己, 服務器的名字也被注冊. 當客戶程序起動時, 到X Server裡查尋 有沒有符合自己 locale類型的輸入服務器(如果用XMODIFIERS指定服務器名, 則同時用locale和名 字區分). 找到後, 根據輸入服務器提供的風格種類 選擇一個最適合自己的風格. 然後客戶程序為每一個需要輸入的窗口都建立 一個自己的標示IC(Input Context), 裡面含有客戶程序的信息, 以後的通訊 則一直使用該標示.

下面是直接使用X Lib和服務器聯接的過程, 在高層函數庫中, 把這一 過程隱藏 了起來:

XIM im; XIC ic; ... if( (im = XOpenIM(display, NULL, NULL, NULL)) == NULL ) { printf("Error : XOpenIM !\n"); exit(0); }

//指定預編輯的類型等... if( (ic = XCreateIC(im, XNInputStyle, XIMPreeditPosition | XIMStatusNothing, XNClientWindow, window, NULL)) == NULL ) { printf("Error : XCreateIC() ! \n"); XCloseIM(im); exit(0); } ...

for(;;) { XNextEvent(display, &event);

//如果輸入服務器接收並處理...繼續 if (XFilterEvent(&event, None) == True) continue; switch(event.type) { case Expose: XmbDrawString(...); case KeyPress: count = XmbLookupString(ic, (XKeyPressedEvent *) &event, string, len, &keysym, &status); ... } }

目前使用比較廣泛的XIM輸入服務器有Chinput(簡體中文, 同時支持繁體), xcin (繁體中文), kinput2(日文) 和 hanIM/ami(韓文).

中文輸入服務器Chinput 選擇了OverTheSpot風格作為缺省的輸入模式, 它與標准 的輸入風格略有不同, 即把預編輯區域偏離輸入位置, 使輸入區 域同時作為狀態 區域, 在很大程度滿足了用戶的輸入習慣. 同時它還使用 輔助工具條顯示和改變 輸入狀態. Chinput還解決了同時使用GB和Big5編碼 的問題, 被動輸入(Passive Input)問題等. 對於普通用戶, 除了使用鍵盤 輸入外, 還可以使用手寫識別輸入 和語音識別輸入方式. 目前的輸入架構 基本能夠滿足它們的要求. 筆者在手寫識 別輸入方面做了一些嘗試, 發 現對絕大部分軟件是能夠適合被動輸入的.

4. 打印的國際化

在X窗口系統下的打印是一個很難解決的問題, 所以到目前為止沒有形成 一個統 一的打印標准. 其原因之一就是X窗口系統在設計上把顯示和打印完全 分開了.

在Linux最常見的需要打印的文件格式是普通文本文件和PostScript文件. 對於中 文的普通文本文件的打印一般需要先轉換為PostScript文件再打印. 對於 PostScript文件, 如果應用軟件在生成時含有中文字體信息, 則打印 比較容易實 現, 反之, 則很難實現甚至不可能打印.

目前中文文本文件常用的打印方法通常是,使用gb2ps/bg2ps/cnprint 等 軟件轉 換成PS文件打印, 轉換過程使用了中文的點陣字體. 對已經形成的PS 文件的打 印, 如果不包含中文字體, 直接打印就會輸出亂碼, 通常使用的方法 是將這一類 PS文件過濾一下, 改為使用中文字體, 然後再打印. 如陳向陽先生 的過濾軟件 ps2cps可以打印Netscape的存儲文件. 這種打印的缺點是有時輸出 的PS中漢字字 符串和英文字符串對不齊. 最好的方法是在PostScript一級實現 中文打印, 陳向 陽先生對ghostscript進行了中文化, 可以直接使用TTF輕松打 印Netscape, Qt/KDE, lyx等軟件輸出的PS文件. 這種從底層實現打印的方法 也是日文和韓文 所采用的方法.

使用CID(adobe)字體打印的方法也在嘗試之中.

總之, 目前的中文打印缺乏統一標准, 應用軟件在輸出打印PS文件時多數 不考慮 雙字節語言的問題, 使打印變得更加復雜化, 所以當前的中文Linux發 布版本多 數不支持中文打印,

5. 客戶程序間通訊的國際化

客戶程序間通訊(Interclient Communications Conventions, 簡稱ICCC)是 客戶 程序之間共享資源的手段之一. 最常見的應用是文本的拷貝和粘貼和與窗口 管理 器通訊. 但是如果兩個應用程序之間所使用的字符集不同, 粘貼就會出現問 題, 甚至粘貼的內容會丟失. 所以客戶程序之間必須國際化了的通訊協議.

應用程序和窗口管理器之間的通訊也屬於客戶程序間通訊.

如果客戶程序之間使用的字符集相同, 但是編碼不同, 則不會丟失數據, 這時應 該使用復合文本(COMPOUND TEXT)傳輸. X內部定義了COMPOUND_TEXT 的原子 (Atom)用於傳輸中英文混和的字符串. 對7字節編碼, ASCII或者其它 ISO8859-1 字符集, 客戶程序通訊可以不用轉換而直接使用XA_STRING原子傳輸.

(第三章完)

待續

相關鏈接: Linux 國際化本地化和中文化(二)


Copyright © Linux教程網 All Rights Reserved