共通デスクトップ環境 プログラマーズ・ガイド (国際化対応編)

第 1 章 国際化対応について

国際化対応とは、コンピュータ・システムとアプリケーションを世界中のユーザに向けて設計することです。世界のユーザは異なる言語を使用しており、操作するシステムの機能性やユーザ・インタフェースに対する要求事項も異なります。これらの差異にもかかわらず、ユーザは世界中のどの場所でも実行できる企業用のアプリケーションの実現を求めています。そのようなアプリケーションは、国境を越えて相互運用できなければならず、複数のベンダから供給されるさまざまなハードウェア構成で実行でき、かつさまざまな国や地域のユーザの要求を満たすようローカライズされていなければなりません。このオープンな分散コンピューティング環境が、共通オープン・ソフトウェア環境の推進力になっています。このマニュアルで説明されている国際化対応テクノロジは、世界市場に上記のような利点を提供します。

国際化対応の概要

1 つの共通オープン・システムには、異なる国語をサポートする複数の環境が存在することがあります。そのような 1 つ 1 つの国の環境はロケールと呼ばれ、言語、文字、フォント、データの入力や書式化の慣習を考慮します。共通デスクトップ環境は、どのアプリケーションでもシステム上にインストールされているすべてのロケールを使用して実行できるように、完全な国際化対応になっています。

ロケールは、プログラムの実行時の動作を、ユーザの地域の言語および慣習に応じて定義します。システム全体を通じて、ロケールは次のことに影響します。

国際化対応アプリケーションには、ユーザのロケール、そのロケールを表すのに必要な文字、ユーザが見て対話したいと思う形式 (日付と通貨など) に依存するコードは含まれません。デスクトップはこれを、言語依存情報と文化依存情報をアプリケーションから分離し、アプリケーション外に保存することによって実現しています。

図 1-1 は、国際化対応をシンプルにするためにアプリケーション外に置かれる情報の種類を示します。

図 1-1 アプリケーションの外の情報

Graphic

言語依存情報と文化依存情報をアプリケーションのソースコードから分離することにより、異なる国々で販売するためにアプリケーションを再記述したり再コンパイルする必要はありません。その代わり、唯一の要求事項は、地域の言語と慣習に適応するように外部情報がローカライズされなければなりません。

国際化対応アプリケーションは、異なる母国語、地域の慣習、文字列のエンコーディングの要求事項に適合できます。オペレーションを特定の母国語、地域の慣習、文字列のエンコーディングに適合させるプロセスを、ローカリゼーション (L10N) と呼びます。国際化対応の目的は、プログラム・ソースを変更したり再コンパイルしなくてもローカリゼーションが可能になることです。

国際化対応の概要を知るには、『X/Open CAE Specification System Interface Definition』Issue 4, X/Open Company Ltd., 1992, ISBN: 1-872630-46-4 を参照してください。

国際化対応の現状

以前は、独自の関数から X/Open の発表する標準関数の新しいセットまで、数多くの種類の国際化対応を業界が提供していました。また、単純な ASCII サポート、ラテン言語/ヨーロッパ言語サポート、アジア言語マルチバイト・サポート、アラビア語/ヘブライ語の両方向サポートなど、レベルもさまざまでした。

X/Open 仕様で定義されたインタフェースは、次のような広範囲の言語および地域をサポートすることができます。

スクリプト 

説明 

ラテン言語 

南北アメリカ、東欧 / 西欧 

ギリシャ語 

ギリシャ 

トルコ語 

トルコ 

東アジア 

日本語、韓国語、中国語 

インド語派 

タイ語 

両方向 

アラビア語とヘブライ語 

共通デスクトップ環境の目的は、これらのテクノロジのローカリゼーション (メッセージおよびマニュアルの翻訳、その他ローカル・ユーザのニーズに合った適合化) を一貫した方法で行うことです。これは、世界中のユーザが、ベンダは違っても同じ共通ローカライズ環境を使用できるようにするためです。エンド・ユーザと管理者は、世界中のソフトウェアをサポートするための完全なアプリケーション環境を提供する、一貫性のあるローカライズ機能を期待できます。

国際化対応の標準

多くの企業の努力を通じて、追加の要求事項および言語 (特に東アジアの言語) を盛り込む過程を経て、国際化対応アプリケーション・プログラム・インタフェースの機能性は標準化されてきました。この作業は主に、POSIX (コンピュータ環境用ポータブル・オペレーティング・システム・インタフェース) および X/Open の仕様に集約されてきました。オリジナルの X/Open 仕様は、第 2 版の『X/Open Portability Guide』(XPG2) で発表され、それは Hewlett-Packard 社がリリースした母国語サポート・プロダクトに基づいています。最も新しく発表された X/Open 国際化対応の標準は、XPG4 と呼ばれます。

デスクトップ内の各階層が、エンド・ユーザが一貫性のあるローカライズされたインタフェースを確保できるように、国際化対応用に定義された適切な標準インタフェース・セットを使用していることが大切です。ロケールと、ロケール依存関数の共通オープン・セットの定義は、次の仕様書に基づいています。

この環境内で、ソフトウェア開発者は、移植性が高く、(ベンダが異なっても) 分散システム間で相互運用でき、デスクトップ標準ロケールでサポートされる多国籍ユーザの多様な言語および文化の要求事項を満たす、世界共通のアプリケーションを開発できます。

共通国際化対応システム

図 1-2 は、国際化対応が特定のシングルホスト・システムに広がる様子を示しています。ゴールは、下位のシステムでサポートされているロケールのセット向けにアプリケーション (クライアント) を構築し、これを世界中で出荷することです。標準インタフェースを使用すると、世界市場への投入しやすさが改善され、アプリケーション開発者が必要とするローカリゼーション作業の量を最小限に減らすことができます。さらに、それぞれの国において、デスクトップの原則を守るシステムで一貫性のあるローカリゼーションを保証できます。

図 1-2 共通国際化対応システム

Graphic

ロケール

ほとんどの単一画面のクライアントは、実行時に環境変数 (通常は $LANG または xnlLanguage リソース) の設定で決定される単一のロケールで動作します。環境を制御するには LC_ALLLC_CTYPELANG などのロケール環境変数を使用できます。詳細は、第 5 章「Xt 依存性と Xlib 依存性」「Xt ロケール管理」を参照してください。

ロケールの LC_CTYPE カテゴリは、環境によって、実行時に使用されるロケール固有の機能を識別するのに使用されます。ツールキットにより読み込まれるフォントおよび入力メソッドは、LC_CTYPE カテゴリで決定されます。

国際化対応されたプログラムは、ユーザの希望するロケールを設定するために XtSetLanguageProc()関数 (デフォルトでは setlocale()) を呼び出すようになっています。ロケールを設定するために setlocale()関数を呼び出すライブラリはないので、特定のロケールまたは実行時に読み込まれた値で XtSetLanguageProc()を呼び出すのはアプリケーションの責任です。アプリケーションが国際化対応なのにXtSetLanguageProc()を使用しない場合は、次の優先順位のソースのいずれかから、setlocale()関数に渡すロケール名を獲得してください。

空の文字列を指定すると、setlocale() 関数がロケールの設定を決定するのに環境変数 $LC_*$LANG を使用します。特に、setlocale (LC_ALL,"") は、表 1-1 に示す順にさまざまなロケール・カテゴリの環境変数のためにロケールがチェックされ選択されます。

表 1-1 ロケール・カテゴリ

カテゴリ 

第 1 環境変数 

第 2 環境変数 

第 3 環境変数 

LC_CTYPE:

LC_ALL

LC_TYPE

LANG

LC_COLLATE:

LC_ALL

LC_COLLATE

LANG

LC_TIME:

LC_ALL

LC_TIME

LANG

LC_NUMERIC:

LC_ALL

LC_NUMERIC

LANG

LC_MONETARY:

LC_ALL

LC_MONETARY

LANG

LC_MESSAGES:

LC_ALL

LC_MESSAGES

LANG

ツールキットはすでに標準のコマンド行オプション (-xnllanguage) およびリソース (xnlLanguage) を定義しています。また、リソースの値は RESOURCE_MANAGER サーバでも設定できます。その場合、RESOURCE_MANAGER サーバに接続するすべてのクライアントに影響する可能性があります。

フォント、フォント・セット、フォント・リスト

すべての X クライアントはテキストを描画するのにフォントを使用します。テキスト描画に使用する基本的なオブジェクトは XFontStruct() です。XFontStruct() は、描画するイメージを含むフォントを識別します。

すでにデスクトップは、Xlib で定義される XFontStruct() データ構造体としてフォントをサポートしています。しかし、フォント内の文字のエンコーディングは国際化対応アプリケーションに認識されていなければなりません。この情報を知るために、プログラムはサーバのすべてのフォントが X 論理フォント (XLFD) 名で識別できることを期待します。XLFD 名により、ユーザは基本特性と charset (フォント・グリフのエンコーディング) の両方を記述できます。charset という用語は、フォント内のグリフのエンコーディングを表すのに使用されます。一方、コード・セットという用語はロケール内の文字のエンコーディングを意味します。指定されたフォントの charset は、XLFD 名の CharSetRegistry フィールドと CharSetEncoding フィールドで決定されます。テキストと記号は、フォント内のコードによって定義されたとおりに描画されます。

フォント・セット (例: Xlib によって定義されるデータ構造体 XFontSet()) は、指定のロケール用に定義されたすべての文字を描画可能にする 1 つ以上のフォントの集合です。ロケールによってはグリフの索引とコード・セットのエンコーディングが一致しない場合がありますが、国際化されたアプリケーションは、このような場合でもテキストを描画できなければなりません。さらに、エンコーディングがロケールのコード・セットと異なるフォントを 1 つ以上使用しているロケールのすべての文字を描画するには、複数のフォントが必要になることがあります。コード・セットと charset は両方ともロケールごとに異なるため、フォント・セットという概念を XFontSet() として実現しています。

フォントが XLFD 名によって識別される一方、フォント・セットは XLFD 名のリストによって識別されます。基本特性のみが重要である点を除き、リストは 1 つ以上の XLFD 名から成ります。必要とされるフォントのエンコーディングはロケールから決定されます。XLFD ベース名リストに指定されている charset はすべて無視されるため、ユーザが考慮する必要があるのはポイント・サイズ、スタイル、ウェートなどのベース特性を指定することだけです。フォント・セットはロケールによって変わり、ロケールのコード・セットでエンコードされたテキストを描画するのに使用されます。国際化対応アプリケーションは、テキスト・データを描画するのにフォント構造体の代わりにフォント・セットを使用すべきです。

フォント・リストは、1 つ以上のフォント・リスト・エントリの集合である libXm Toolkit オブジェクトです。フォント・セットはフォント・リストで指定できます。各フォント・リスト・エントリは、フォントかフォント・セットのいずれかを指定し、名前がタグ付けされます。フォント・リスト・エントリにタグがない場合は、デフォルト・タグ (XmFONTLIST_DEFAULT_TAG) が使用されます。フォント・リストは、libXm Toolkit ライブラリにある XmString() 関数と共に使用できます。フォント・リストにより、1 つ以上のセグメント (各セグメントはタグで識別される) から成るコンパウンド・ストリングの描画が可能になります。これにより、異なる基本特性を持つ文字列の描画が可能になります (たとえば、1 回のオペレーションでボールドとイタリックの文字列を描画できます)。libXm ライブラリの XmText() など一部の XmString() ベースではないウィジェットは、フォント・リストでフォント・リスト・エントリを 1 つしか使用しません。Motif フォント・リストは、フォント・リスト内のフォント・セットを識別するために接尾辞 : (コロン) を最後につけます。

通常、ユーザは (フォントかフォント・セットのいずれかが含まれている) フォント・リストか、またはフォント・セットを指定するよう要求されます。国際化対応環境では、ユーザはコード・セットに依存しないフォントを指定できなければなりません。というのは、その指定は、フォントの文字セット (charset) よりも、異なるコード・セットを持つさまざまなロケールで使用されるからです。したがって、すべてのフォント・リストにはフォント・セットを指定するようにしてください。

フォント指定

フォント指定は、X 論理フォント (XLFD) 名か、XLFD 名の別名のいずれかになります。たとえば、次の例はどちらも 14 ポイント・フォントの有効なフォント指定です。

-dt-application-medium-r-normal-serif-*-*-*-*-p-*-iso8859-1

または

-*-r-*-14-*iso8859-1

フォント・セット指定

フォント・セット指定は、名前 (XLFD 名かその別名) のリストであり、ベース名リストと呼ばれることもあります。すべての名前はカンマで区切られ、カンマの前後にある空白スペースはすべて無視されます。XLFD 名を短縮するためにパターン照合 (ワイルドカード) 文字を指定できます。

フォント・セット指定は、実行中のロケールによって決定されることに注意してください。たとえば、日本語ロケール ja_JP は、日本語のすべての文字を表示するのに必要な 3 つのフォント (文字セット) を定義します。次の例では必要なゴシック・フォントのセットが識別されます。

上記の 2 例は、ベース名リストに一致するフォントが存在する限り日本語ロケールで使用できます。

フォント・リスト指定

フォント・リスト指定は 1 つ以上のエントリから成り、各エントリはフォント指定かフォント・セット指定のいずれかになります。

各エントリには、コンパウンド・ストリングを描画するときに使用される名前がタグ付けされます。タグはアプリケーションで定義され、通常はフォントの種類が予想できるような名前です (bold()italic()bigbold() など)。ヌルのタグはデフォルト・エントリを表すのに使用され、XmString() 関数で使用される XmFONTLIST_DEFAULT_TAG 識別子に関連付けられます。

フォント・タグは、= (等号記号) が接頭部に付くときに識別されます。たとえば、=bigbold() はサーバで定義された最初のフォントに一致します。= が指定されていてもその後に名前がない場合は、その指定は「デフォルト・フォント・リスト・エントリ」と見なされます。

フォント・セット・タグは、: (コロン) が接頭部に付くときに識別されます。たとえば、:bigbold() はロケールの条件を満たす、サーバの最初のフォント・セットに一致します。: が指定されていても名前が指定されていない場合は、その指定はデフォルト・フォント・リスト・エントリと見なされます。フォント・リスト・エントリ指定内では、ベース名リストは , (カンマ) ではなく ; (セミコロン) で区切られます。

フォント・リスト指定の例

ラテン 1 ロケール用には、次のように入力します。

   -*-r-*-14-*: ,      # default font list entry
   -*-b-*-18-*:bigbold # Large Bold fonts

ベース・フォント名リスト指定

ベース・フォント名リストは、ロケールによって定義されたフォント・セットに関連付けられたベース・フォント名のリストです。ベース・フォント名はカンマで区切られたリストであり、ポータブル文字セットからの文字だと想定されます。そうでない場合の結果は不定です。セパレータのカンマに隣接する空白スペースは無視されます。

XLFD フォント名の使用により、国際化対応のアプリケーションが、単一のロケールに依存しないベース・フォント名からさまざまなロケールに必要なフォントを得ることができます。単一のベース・フォント名は、該当ロケールに必要なさまざまな charset でメンバがエンコードされたフォントのファミリを指します。

XLFD ベース・フォント名は、ロケールに必要なフォントの charset を明示的に指定できます。このことにより、ユーザはロケールに必要な charset で使用するフォントを厳密に指定することができるので、フォント選択を完全に制御できます。

ベース・フォント名が XLFD 名でない場合は、フォントのフォント属性から XLFD 名を獲得しようとします。

次のアルゴリズムは、フォント・セットでテキストを表示するのに使うフォントを選択するために使用されます。

ロケールに必要な各 charset ごとに、ベース・フォント名リストはサーバに存在するフォント・セットを指定する以下の場合の最初にあてはまるものが検索されます。

たとえば、ロケールには次の charset が必要だと想定します。

次の例のように、charset を明示的に指定したベース・フォント名リストを提供し、特定のフォントが存在する場合には確実に使用するようにできます。

"-dt-mincho-Medium-R-Normal-*-*-*-*-*-M-*-JISX0208.1983-0,¥
-dt-mincho-Medium-R-Normal-*-*-*-*-*-M-*-JISX0201.jisx0201¥.1976-1,¥
-dt-song-Medium-R-Normal-*-*-*-*-*-M-*-GB2312-1980.0,¥
-*-default-Bold-R-Normal-*-*-*-*-M-*-ISO8859-1"

次の例のように、charset を省いたベース・フォント名リストを提供すると、必要な各コード・セット用のフォントを選択できます。

"-dt-Fixed-Medium-R-Normal-*-*-*-*-*-M-*,¥
-dt-Fixed-Medium-R-Normal-*-*-*-*-*-M-*,¥
-dt-Fixed-Medium-R-Normal-*-*-*-*-*-M-*,¥
-*-Courier-Bold-R-Normal-*-*-*-*-M-*"

代わりの方法として、次の例のように単一ベース・フォント名を提供すると、ある最小の XLFD 属性要求事項を満たす使用可能なすべてのフォントから選択できます。

"-*-*-*-R-Normal--*-*-*-*-*-M-*"

テキスト描画

デスクトップは、シンプルなテキスト、コンパウンド・ストリング、数種類のウィジェットを含むローカライズされたテキストを受け渡すさまざまな関数を提供します。これらの中には Xlib ライブラリと Motif ライブラリの関数も含まれます。

入力メソッド

共通デスクトップ環境は、Xm Toolkit を使用する国際化対応したアプリケーションに対して、ローカライズされた入力を行う機能を提供します。特に、XmText[Field]() ウィジェットが、各ロケールで提供される入力メソッドとインタフェースすることが可能になります。さらに、dtterm() クライアントも、入力メソッドを使用することが可能になります。

デフォルトでは、libXm Toolkit を使用するそれぞれの国際化対応クライアントは、ユーザの指定したロケールに関連付けられた入力メソッドを使用します。ユーザが代替入力メソッドを自由に指定できるように、XmNinputMethod() リソースがロケール名のモディファイアとして提供されます。

入力メソッドのユーザ・インタフェースは複数の要素から構成されています。それらの領域の必要性は、使用されている入力メソッドによります。通常それらの要素は、複雑な入力処理とダイアログを要求する入力メソッドの場合に必要となります。

図 1-3 VendorShell ウィジェットと補助の例 (日本語)

Graphic

プリエディット領域

プリエディット領域は、あらかじめ編集される (プリエディット) 文字列を表示するのに使用されます。入力メソッドは、次の 4 つのプリエディット・モードをサポートしています。OffTheSpot、OverTheSpot (デフォルト)、Root、および None です。


注 -

確定した文字列は再変換できません。文字列の状態は、プリエディット領域から、ユーザが文字を入力している位置へ移動します。


OffTheSpot

入力メソッドを使用する OffTheSpot モードのプリエディットでは、プリエディットの位置は図 1-4 のようにメイン・ウィンドウ領域のすぐ下かつステータス領域の右側に固定されています。日本語の入力メソッドを例示します。

図 1-4 VendorShell ウィジェットでの OffTheSpot プリエディットの例 (日本語)

Graphic

システム環境では、入力メソッドを使用してプリエディットすると、編集されているプリエディット文字列が、入力メソッドによって何らかの形で強調表示されます。

OffTheSpot モードを使用するには、VendorShell()ウィジェットのXmNpreeditType() リソースを、XtSetValues() 関数かリソース・ファイルのどちらかで設定します。XmNpreeditType() リソースは、TopLevelShell()ApplicationShell()DialogShell() ウィジェットのリソースとしても設定できます。この 3 つのウィジェットは、VendorShell() ウィジェット・クラスのサブクラスです。

OverTheSpot (デフォルト)

OverTheSpot モードでは、プリエディット領域の位置はユーザが文字を入力しようとする場所 (たとえば現在のフォーカスを持つ Text ウィジェットの挿入カーソルの位置) に設定されています。プリエディット領域の文字は、カーソル位置にオーバレイ・ウィンドウとして表示され、入力メソッドによっては強調表示されます。

OverTheSpot モードでは 1 つのプリエディット領域が複数の行から成る場合があります。プリエディット領域は常にメイン・ウィンドウ領域の中にあり、どの方式でもはみ出すことはありません。

プリエディット中の文字列が Text ウィジェットのテキストの一部であるかのように表示されていても、プリエディットが終了するまでは、クライアントに渡されて下位の編集画面に表示されることはないので注意してください。図 1-5 を参照してください。

OverTheSpot モードを明示的に使用するには、VendorShell() ウィジェットの XmNpreeditType() リソースを、XtSetValues() 関数かリソース・ファイルのどちらかで設定します。XmNpreeditType() リソースは、TopLevelShell()ApplicationShell()、またはDialogShell() ウィジェットのリソースとしても設定できます。この 3 つのウィジェットは、VendorShell() ウィジェット・クラスのサブクラスです。

図 1-5 VendorShell ウィジェットでの OverTheSpot プリエディットの例 (日本語)

Graphic

Root

Root モードでは、プリエディット領域およびステータス領域はクライアントのウィンドウとは別になっています。Root モードの動作は OffTheSpot に似ています。図 1-6 を参照してください。

図 1-6 VendorShell ウィジェットでの Root プリエディットの例 (日本語)

Graphic

ステータス領域

ステータス領域は、入力メソッドの入力ステータスまたはキーボード・ステータスをユーザに報告します。OverTheSpot および OffTheSpot の形式では、ステータス領域は VendorShell ウィンドウの左下隅に位置します。

VendorShell() ウィジェットは、VendorShell ウィンドウがサイズ変更された場合にステータス領域が VendorShell ウィンドウの下隅に再配置できるように、ジオメトリ管理を提供しています。

補助領域

補助領域はユーザがプリエディットを行うときに役立ちます。補助領域は特定の入力メソッドにより作成できます。図 1-3 に示した日本語の入力メソッドは、次の型の補助領域を作成します。

メイン・ウィンドウ領域

メイン・ウィンドウ領域は、入力メソッドの作業対象の領域として使用されるウィジェットです。システム環境では、VendorShell() ウィジェットの子として作れるのは MainWindow ウィジェットだけです。MainWindow ウィジェットは、どんなコンテナ・ウィジェットだけにもなり得ます (RowColumn() ウィジェットなど)。ユーザはコンテナ・ウィジェットを VendorShell() ウィジェットの子として作成します。

フォーカス領域

フォーカス領域は、現在フォーカスを持っている MainWindow() ウィジェット・サブツリーの下のすべての子孫ウィジェットのうちの一つです。既存のウィジェットを使用している Motif アプリケーション・プログラマは、フォーカス領域を気にする必要はありません。重要なのは、一度に 1 つのウィジェットだけしか入力メソッドを処理できないということです。入力メソッドの処理は、現在フォーカスを持つウィンドウ (ウィジェット) に移動します。

クライアント間通信規約 (ICCC)

クライアント間通信規約 (ICCC) は、クライアント間でテキストを渡すのに使用する機構を定義します。システムは複数のコード・セットをサポートできるので、異なるコードセットを使用している 2 つのアプリケーションが互いに通信し合うことも可能です。ICCC は、2 つのクライアント間のデータの渡し方に関して、これらのクライアントがどのように同意するかを定義します。2 つのクライアントの持つ文字セットに互換性がない場合 (たとえばラテン 1 と日本語 (JIS) のように)、文字を転送するときにデータの一部が失われる可能性があります。

しかし、2 つのクライアントが、コード・セットは異なるが文字セットに互換性がある場合は、ICCC はこれらのクライアントがデータを失わずに情報を渡せるようにします。2 つのクライアントのコード・セットが等しくない場合は、COMPOUND_TEXT アトムを使用して、コンパウンド・テキストのエンコーディングが使用されます。通信中のデータにポータブルな文字 (7 ビット、ASCII、その他) または ISO8859-1 コード・セットしか含まれない場合は、データは XA_STRING アトムにより、変換なしでそのまま通信されます。

タイトル名とアイコン名は、ポータブルでない文字を使用する場合、COMPOUND_TEXT アトムを使用してウィンドウ・マネージャへ通信される必要があります。そうでない場合は、XA_STRING アトムを使用できます。その他のエンコーディングは、ウィンドウ・マネージャのロケールへ変換する程度に制限されています。ウィンドウ・マネージャは単一のロケールで実行され、実行中のロケールのコード・セットに変換できるタイトルとアイコン名しかサポートしません。

libXm ライブラリとすべてのデスクトップ・クライアントは、これらの規約に従う必要があります。