CTL (Complex Text Layout) 拡張機能により、アラビア語、ヘブライ語、タイ語など論理テキスト表現と物理テキスト表現の間の複雑な変換が必要な言語を Motif の API で用いることができます。CTL Motif では文字の整形 (合字、区別的発音符、セグメントの順序の決定など) を行うことができます。また、静的および動的なテキストウィジェットがサポートされています。さらに、テキストの方向を選択したり (右から左または左から右)、動的なテキストウィジェットにタブを使用したりすることができます。テキストのレンダリングはレンディション層を通じて処理されるので、その他のウィジェットライブラリの CTL サポートへの拡張は容易です。
新機能を利用するには、PLS (Portable Layout Services) ライブラリおよび適切な言語エンジンを用意する必要があります。CTL は言語エンジンとのインタフェースとして PLS を使い、レンダリングを実行する前に言語エンジンを使ってテキストを変換します。CTL をサポートするアプリケーションは、CTL のマニュアルに指定されているリソースをあらかじめインクルードする必要があります。
XmCTL でサポートされる、言語の複雑な整形および再配置機能について、以下に具体的に示します。これらの機能は、ロケールごとに異なるる PLS モジュールの行う変換を通じて提供されます。
下図に CTL アーキテクチャの構成を示します。表の上に位置する Dt Apps は Motif CTL 機能を用いてテキストのレンダリングを行います。これを受けて、Motif はロケールに固有の言語エンジンと PLS 経由でインタフェースし、位置の変更、数値の整形などの操作を行います。
目的のロケールに固有のエンジンを追加するだけで、CTL アーキテクチャに新しい言語をサポートさせることができます。つまり、Motif や Dt Apps を変更することなくタイ語やベトナム語をサポートすることができます。
XmNlayoutDirection [XmNlayoutDirection の概要、特に XmStringDirection と XmNlayoutDirection の相互作用については『Motif Programmer's Guide (Release 2.1)』のセクション 11.3 を参照してください。] リソース (1) はオブジェクトレイアウトを制御します。XmNlayoutDirection を用いて LayoutObject の方向の値を指定する方法を以下に示します。
XmNlayoutDirection が XmDEFAULT_DIRECTION として指定されている場合、ウィジェットのレイアウトの方向は作成時に支配的な疑似 XOC により設定されます。動的テキスト (Xmtext および XmTextField) では、ウィジェットに使用されている XmRendition に関連付けされた疑似 XOC が支配的疑似 XOC になります。静的テキスト (Xmlist、XmLabel、XmLabelG) のレイアウト方向は、方向の指定されている最初の合成文字列コンポーネントに基づいて設定されます。次の 2 通りのいずれかで指定します。
直接的に指定。コンポーネントの種類が XmSTRING_COMPONENT_LAYOUT_PUSH または XmSTRING_COMPONENT_DIRECTION の場合
間接的に指定。コンポーネントの種類が XmSTRING_COMPONENT_LOCALE_TEXT、XmSTRING_COMPONENT_WIDECHAR_TEXT または XmSTRING_COMPONENT_TEXT の場合。コンポーネントに関連付けされた XmRendition に関連付けされた LayoutObject から設定
XmNlayoutDirection が XmDEFAULT_DIRECTION として指定されていない場合、XmNlayoutModifier @ls orientation の値がレイアウト修飾子文字列に明示的に指定されていなければ、XmnlayoutDirection の値は XOC およびその LayoutObject に受け渡されます。
XmNlayoutDirection と XmNlayoutModifier @ls orientation の両方の値が明示的に指定されている場合、上記の動作の中間になります。ウィジェットオブジェクトのレイアウトは XmNlayoutDirection により制御され、レイアウトの変換は XmNlayoutModifier @ls orientation の値により制御されます。
より詳細な情報については、CAE 基準『Portable Layout Services: Context-dependent and Directional Text』(The Open Group: Feb 1997; ISBN 1-85912-142-X; document nu mber C616) を参照してください。
XmStringDirection は、文字列に含まれる各文字の表示方向を指定するデータ形式です。
XmStringDirection リソースは、文字列の方向を指定するコンポーネントを持たないすべての複合文字列 (XmString) に対してデフォルトのレンダリング方向を設定します。したがって、XmStringDirection リソースに対して適切な値を設定するだけで、レイアウト方向を設定できます。複合文字列の各コンポーネントの方向を指定する必要はありません。アプリケーションにおいて XmString がレンダリングされる場合、その文字列が方向 (XmStringDirection) を明示して作成されたかどうかが確認されます。方向コンポーネントが存在しなければ、アプリケーションは XmNlayoutDirection リソースの値から現在のウィジェットを確かめ、その値を XmString のデフォルトのレンダリング方向として使用します。
XmRendition および XmDirection も参照してください。
CTL により、以下に示す新しい疑似リソースが XmRendition に追加されました。
名前 |
クラス/タイプ |
アクセス |
デフォルト値 |
---|---|---|---|
XmNfontType |
XmCFontType/XmFontType |
CSG |
XmAS_IS |
XmNlayoutAttrObject |
XmClayoutAttrObject/String |
CG |
NULL |
XmNlayoutModifier |
XmCLayoutModifier/String |
CSG |
NULL |
レンディションフォントオブジェクトのタイプを指定します。CTL では、このリソースの値が XmFONT_IS_XOC の値になっている必要があります。それ以外の値が設定されていると、XmNlayoutAttrObject と XmNlayoutModifier の値は無視されます。
XmNfontType リソースの値が XmFont_IS_XOC で、XmNfont リソースが指定されていない場合、XmNfontName リソースの名前は、その作成時点で XmlayoutAttrObject リソースにより指定されたロケール、または現在のロケールの XOC オブジェクトに変換されます。さらに、XmNlayoutModifier リソースの値は XOC に関連付けられた任意の LayoutObject にパススルーされます。
この XmRendition に関連付けられた XOC に関連付けられた Layout Object の作成に使用されるレイアウト AttrObject 引数を指定します。この文字列の構文およびセマンティクスについては、レイアウトサービス m_create_layout() の仕様を参照してください。Layout Modifier Orientation の出力値と XmNlayoutDirection のウィジェットリソースの相互作用については、上述の XmNfontType の説明を参照してください。
XmRendition に関連付けられた XOC に関連付けられた Layout Object にパススルーされるレイアウト値を指定します。この文字列の構文およびセマンティクスについては『CAE Specification』を参照してください。
XmRendition{retrieve,Update} を用いてこのリソースを設定すると、文字列はこの Rendition に関連付けられた XOC に関連付けられた LayoutObject にパススルーされます。レイアウトサービスは以上の手続きにより動的に構成されます。 Orientation、 Context、 TypeOfText、 TextShaping、または ShapeCharset を変更すると、予測不能な動作が生じる可能性があります。
XmNlayoutModifier は、XmRendition に関連付けられたテキストのレイアウト動作に影響します。たとえば、数値のレイアウトデフォルト処理が NUMERALS_NOMINAL ならば、XmNlayoutModifier を次の 2 つのどちらかに従って設定することにより NUMERALS_NATIONAL に変更することができます。
レイアウト値は以下の各グループに分類できます。
エンコーディング記述 : TypeOfText、TextShaping、ShapeCharset (およびロケールのコードセット)
TypeOfText はセグメント順であり、未使用ブロックとして表すことができます。通常、Rendition オブジェクトを通じてこれらの値を動的に変更することは無意味です。ほとんどの場合、予測不能な動作を生じる結果となります。
レイアウト動作: Orientation、Context、ImplicitAlg、Swapping、NumeralsOrientation、および Context は動的に変更してはいけません。ImplicitAlg、Swapping、および Numerals を変更するようにしてください。
Xm CTL では、XmText と XmTextField が拡張され、ビジュアル的な移動機能と削除機能が追加されました。これは Motif 2.0 CSText ウィジェット以降の機能です。Motif 2.1 の標準の Text および TextField では、論理的順序と物理的順序は区別されません。「次」および「前方」は「右へ」を意味し、「前」および「後方」は「左へ」を意味します。一方、CSText ではこれらは区別されており、物理名だけを用いる一連の動作が新たに定義されています。これらには、たとえば left-character()、delete-right-word() などがあります。これらの処理ルーチンはすべてウィジェットの XmNlayoutDirection に依存するように定義されていて、適切な「次の〜」または「前の〜」の動作が呼び出されます。Xm CTL の拡張は CSText の場合よりも多少複雑です。これは、ウィジェットのグローバルな方向だけでなく、疑似 XOC (中立安定を含む) により決定されるカーソルの周囲の物理文字の個々の方向性にも依存するためです。
さらに、選択基準を決定し、レンディションのタグを提供し、揃え方を決定する新しいリソースが追加されています。
新しい Xm CTL の動作は、{Move,Delete,Kill} と {Left,Right} と {Character,Word} を一つに合成したような動作になっています。以下にその詳細について説明します。
XmText および XmTextField に対して以下の各リソースが追加されています。
名前 |
クラス/種類 |
アクセス |
デフォルト値 |
---|---|---|---|
XmNrenditionTag |
XmCRenditionTag/XmRString |
CSG |
XmFONTLIST_DEFAULT_TAG |
XmNalignment |
XmCAlignment/XmRAlignment |
CSG |
XmALIGNMENT_BEGINNING |
XmNeditPolicy |
XmCEditPolicy/XmREditPolicy |
CSG |
XmEDIT_LOGICAL |
このウィジェットに対して使用される XmRendition のレンディションタグを指定します。XmRendition は XmnrenderTable リソースに含まれます。
ウィジェット内で使用されるテキストの揃え方を指定します。XmALIGNMENT_END と XmALIGNMENT_CENTER だけがサポートされています。
ウィジェットに対して使用される編集の基準を XmEDIT_LOGICAL または XmEDIT_VISUAL として指定します。XmEDIT_VISUAL を指定すると、選択、カーソル移動、および削除は視覚的に行われます。このリソースを設定すると、同時に標準のキーボード操作の変換規則および削除イベントも、以下に示す新しい「視覚的」な動作リストまたは既存の論理動作に変更されます。
以下のリストに含まれる動作はすべて、指定された方向にある文字の向きの問い合わせを行います。たとえば方向が左から右ならば、対応する形式として next-/forward- または previous-/backward- が呼び出されます。
delete-left-character()
delete-left-word()
delete-right-character()
delete-right-word()
kill-left-character()
kill-left-word()
kill-right-character()
kill-right-word()
left-character()
left-word()
prev-cell()
right-character()
right-word()
forward-cell()
Layout Services 変換の OutToInp および Property バッファ (入れ子のレベル用) を使用して、文字の向きを決定します。したがって、ウィジェットの動作は各ロケール固有の変換に依存します。OutToInp バッファや Property バッファの情報が正しくないと、ウィジェットが予想外の動作を行うことがあります。特に Property バッファの情報は大きく影響します。ロケール固有のモジュールがこの仕様の適用範囲から外れている場合、同じテキスト、アプリケーション、リソース値、および LayoutObject 構成に対して行われる双方向の編集動作が、プラットフォームによって異なる場合があります。
ビジュアルモードの動作は表示セルベースの動作を生じます。論理モードの動作は論理的な文字ベースの動作を生じます。たとえば、delete-right-character() では、ディスプレイセルに対応した入力バッファの文字が削除されます。(つまり、LayoutObject 変換の「プロパティ」バイトの「新しいセルのインジケータ」が 1 に設定されている入力バッファの文字 1 個、および「新しいセルのインジケータ」 [Property バッファの詳細については、CAE Specification の m_transform_layout() の仕様を参照してください。] が 0 である後続のすべての文字が消去されます。)
同様に、backward-character() では入力バッファ内で挿入点が 1 つ前に移動します。これに伴い、カーソルは出力バッファ内で関連付けられた文字に対応する表示上の位置に再描画されます。これは、複合表示セル上を移動するにはキーストロークを繰り返す必要があることを意味します。つまり「新しいセルのインジケータ」が 0 の入力バッファ文字 (区別的発音符または合字) を横切って挿入点が移動するため、カーソルの表示位置は実際には変化しません。
このことは、削除動作が論理/入力バッファ側から実行されるか、物理的/出力側の表示セルレベルから実行されることを意味します。入力バッファと出力バッファの間には 1 対 1 の対応関係が存在しないため、厳密な意味での 1 文字単位の削除モードは存在しません。たとえば、1 つの物理文字が論理文字の一部分だけを表しているような場合が考えられます。
XmText の動作ルーチンを以下に示します。
XmNeditPolicy が XmEDIT_LOGICAL で、引数なしで呼び出された場合、挿入カーソルは 1 論理文字分だけ前に移動します。挿入カーソルが行の先頭にある場合、1 つ前の行があればその行の最後の論理文字に移動します。1 つ前の行が存在しない場合には、カーソル位置は変化しません。
XmNeditPolicy が XmEDIT_VISUAL ならば、カーソルは 1 つ左に移動します。挿入カーソルが行の先頭にある場合、1 つ前の行があればその行の最後の論理文字に移動します。
extend 引数を指定して left-character() が呼び出されると、現在の選択範囲を延長させながら、引数なしの場合と同じように挿入カーソルを移動します。
left-character() 動作は、reason の値として XmCR_MOVING_INSERT_CURSOR を用いて XmNmotionVerifyCallback プロシージャを呼び出します。extend 引数を指定して呼び出された場合、XmNgainPrimaryCallback プロシージャが呼び出されることがあります。詳細については『Motif Programmer's Reference』のコールバックに関する説明を参照してください。
XmNeditPolicy が XmEDIT_LOGICAL で、引数なしで呼び出された場合、挿入カーソルがワードの論理的開始位置にあれば、挿入カーソルは 1 つ前の論理ワードの開始位置に移動します。1 つ前の論理ワードが存在しない場合には、挿入カーソルの位置は変化しません。ワード内の、ワードの論理的な先頭以外に挿入カーソルが位置している場合には、挿入カーソルはワードの論理的開始位置に移動します。挿入カーソルが行の論理的開始位置にある場合、挿入カーソルを 1 つ前の行の論理的な最後のワードの始点に移動します。1 つ前の行が存在しない場合には、挿入カーソルの位置は変化しません。
XmNeditPolicy が XmEDIT_VISUAL で、引数なしで left-word() が呼び出されると、左側または行の先頭以降の最初の白い空白文字の後の、白以外の最初の空白文字に挿入カーソルを移動します。挿入カーソルがすでにワードの先頭に位置している場合、1 つ前のワードの先頭に挿入カーソルを移動します。挿入カーソルがすでに行の先頭にある場合、1 つ前の行の最後のワードの先頭に移動します。
extend 引数を指定して left-word() が呼び出されると、現在の選択範囲を延長させながら、引数なしの場合と同じように挿入カーソルを移動します。
left-word() 動作は、reason の値として XmCR_MOVING_INSERT_CURSOR を用いて XmNmotionVerifyCallback プロシージャを呼び出します。extend 引数を指定して呼び出される場合、XmNgainPrimaryCallback プロシージャが呼び出されることがあります。詳細については『Motif Programmer's Reference』のコールバックに関する説明を参照してください。
XmNeditPolicy が XmEDIT_LOGICAL で、引数なしで呼び出された場合、挿入カーソルを 1 論理文字分だけ次に移動します。挿入カーソルが行の論理的な最後尾にある場合、次の行があればその行の先頭に挿入カーソルを移動します。
XmNeditPolicy が XmEDIT_VISUAL ならば、カーソルは 1 つ右に移動します。挿入カーソルが行末にある場合、次の行があればその行の最後の論理文字に移動します。
extend 引数を指定して right-character() が呼び出された場合、現在の選択範囲を延長させながら、引数なしの場合と同じように挿入カーソルを移動します。
right-character() 動作は、reason の値として XmCR_MOVING_INSERT_CURSOR を用いて XmNmotionVerifyCallback プロシージャを呼び出します。extend 引数を指定して呼び出される場合、XmNgainPrimaryCallback プロシージャが呼び出される場合があります。詳細については『Motif Programmer's Reference』のコールバックに関する説明を参照してください。
XmNeditPolicy が XmEDIT_LOGICAL で、引数なしで呼び出された場合、挿入カーソルは次の論理ワードの開始位置に移動します。次の論理ワードが存在しない場合には、現在のワードの論理的な最後尾に挿入カーソルを移動します。挿入カーソルが行の論理的な最後尾にあるか、行の論理的な最後のワード内にある場合、挿入カーソルは次の行の論理的な先頭ワードに移動します。次の行が存在しない場合、挿入カーソルは現在のワードの論理的な最後尾に移動します。
XmNeditPolicy が XmEDIT_VISUAL で、right-word() が引数なしで呼び出された場合、右側または行末以降の最初の白い空白文字の後の、白以外の最初の空白文字に挿入カーソルを移動します。
extend 引数を指定して right-word() が呼び出された場合、現在の選択範囲を延長させながら、引数なしの場合と同じように挿入カーソルを移動します。
right-word() の動作は、reason の値として XmCR_MOVING_INSERT_CURSOR を用いて XmNmotionVerifyCallback プロシージャを呼び出します。extend 引数を指定して left-word() が呼び出される場合、XmNgainPrimaryCallback プロシージャが呼び出される場合があります。詳細については『Motif Programmer's Reference』のコールバックに関する説明を参照してください。
XmNeditPolicy が XmEDIT_LOGICAL ならば、delete-previous-char と同じです。XmNeditPolicy が XmEDIT_VISUAL ならば、次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の 1 文字が削除されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されず、XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の 1 文字が削除されます。結果が選択内容に影響を与える場合があります。
delete-left-character() 動作は、reason の値として XmCR_MODIFYING_TEXT_VALUE を用いて XmNmodifyVerifyCallback プロシージャを呼び出します。また、reason の値として XmCR_VALUE_CHANGED を用いて XmNvalueChangedCallback プロシージャを呼び出します。
XmNeditPolicy が XmEdit_LOGICAL ならば、delete-next-character と同じです。XmNeditPolicy が XmEDIT_VISUAL ならば、次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の 1 文字が削除されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されず、XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の 1 文字が削除されます。結果が選択内容に影響を与える場合があります。
delete-right-character() 動作は、reason の値として XmCR_MODIFYING_TEXT_VALUE を用いて XmNmodifyVerify-Callback プロシージャを呼び出します。また、reason の値として XmCR_VALUE_CHANGED を用いて XmNvalue- ChangedCallback プロシージャを呼び出します。
XmNeditPolicy が XmEDIT_VISUAL ならば、delete-prev-word() が引数なしで呼び出された場合と同じです。XmNeditPolicy が XmEDIT_LOGICAL ならば次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の文字から次の空白文字、句読点、タブ、または行頭の文字まで削除されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されず、XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の文字から次の空白文字、句読点、タブ、または行頭の文字までが削除されます。結果が選択内容に影響を与える場合があります。
XmNeditPolicy が XmEDIT_VISUAL ならば、kill-right-word() と同じです。XmNeditPolicy が XmEDIT_LOGICAL ならば次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の文字から次の空白文字、句読点、タブ、または行末の文字まで削除されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されず、XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の文字から次の空白文字、句読点、タブ、または行末の文字まで削除されます。結果が選択内容に影響を与える場合があります。
XmNeditPolicy が XmEDIT_LOGICAL ならば、kill-prev-char と同じです。XmNeditPolicy が XmEDIT_VISUAL ならば次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の 1 文字が消去されます。消去された文字はカットバッファに保存されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されず、XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の 1 文字が削除されます。結果が選択内容に影響を与える場合があります。
kill-left-character() の動作は、reason の値として XmCR_MODIFYING_TEXT_VALUE を用いて XmNmotionVerifyCallback プロシージャを呼び出します。さらに、reason の値として XmCR_VALUE_CHANGED を用いて XmNvalueChangedCallback プロシージャを呼び出します。
XmNeditPolicy が XmEDIT_LOGICAL ならば、delete-next-character と同じです。XmNeditPolicy が XmEDIT_VISUAL ならば次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の 1 文字が消去されます。消去された文字はカットバッファに保存されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されず、XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の 1 文字が削除されます。結果が選択内容に影響を与える場合があります。
kill-right-character() の動作は、reason の値として XmCR_MODIFYING_TEXT_VALUE を用いて XmNmotionVerifyCallback プロシージャを呼び出します。さらに、reason の値として XmCR_VALUE_CHANGED を用いて XmNvalueChangedCallback プロシージャを呼び出します。
XmNeditPolicy が XmEDIT_VISUAL ならば、delete-prev-word() と同じです。XmNeditPolicy が XmEDIT_LOGICAL ならば次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの左側の文字から次の空白文字、句読点、タブ、または行頭の文字まで削除されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されません。範囲が選択されていない場合は、挿入カーソルの左側の文字から次の空白文字、句読点、タブ、または行頭の文字までが削除され、削除された内容がカットバッファに保存されます。結果が選択内容に影響を与える場合があります。
XmNeditPolicy が XmEDIT_VISUAL ならば、delete-right-word() と同じです。XmNeditPolicy が XmEDIT_LOGICAL ならば次のようになります。すなわち、通常モードで範囲が選択されている場合は、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の文字から次の空白文字、句読点、タブ、または行末の文字まで削除されます。追加モードで、選択されている範囲がある場合は、カーソルは選択範囲から切り離されません。XmNpendingDelete が True に設定され、選択された部分が削除されます。範囲が選択されていない場合は、挿入カーソルの右側の文字から次の空白文字、句読点、タブ、または行末の文字までが削除され、削除された内容がカットバッファに保存されます。結果が選択内容に影響を与える場合があります。
文字合成、合字、区別的発音符などをサポートするため、セルベースのルーチンが提供されています。つまり、1 個のプレゼンテーションセルを占有する 1 個のグリフを用いて、複数の文字を表すことができます。
XmText セルの動作ルーチンを以下に示します。
1 セル分、挿入カーソルを前に移動します。XmNeditPolicy が XmEDIT_LOGICAL ならば、現在のセルよりも論理的に 1 つ前のセルの先頭に挿入カーソルが移動します。1 つ前のセルが存在しない場合には、挿入カーソルは現在のセルの先頭に移動します。
XmNeditPolicy が XmEDIT_VISUAL ならば、カーソルはその左側のセルの先頭に移動します。prev-cell() 動作は、reason の値として XmCR_MOVING_INSERT_CURSOR を用いて XmNmotionVerifyCallback プロシージャを呼び出します。また、引数を指定して呼び出された場合、XmNgainPrimaryCallback プロシージャへの呼び出しが発生する場合があります。詳細については『Motif Programmer's Reference』のコールバックに関する説明を参照してください。
論理的な次のセルの始点に挿入カーソルを移動します。1 つ前のセルが存在しない場合には、現在のセルの最後尾にカーソルを移動します。XmNeditPolicy が XmEDIT_LOGICAL ならば、次のセルにカーソルを移動します。
XmNeditPolicy が XmEDIT_VISUAL ならば、カーソルはその右側のセルの先頭に移動します。右側にセルが存在しない場合、カーソルは現在のセルの最後尾に移動します。 forward-cell() 動作は、reason の値として XmCR_MOVING_INSERT_CURSOR を用いて XmNmotionVerifyCallback プロシージャを呼び出します。また、引数を指定して呼び出された場合、XmNgainPrimaryCallback プロシージャへの呼び出しが発生する場合があります。詳細については『Motif Programmer's Reference』のコールバックに関する説明を参照してください。
この TextField 関数はレイアウト修飾子の文字列を返します。返された文字列はレンディションに用いられるレイアウトオブジェクトの状態を示します。
#include <Xm/TextF.h>String XmTextFieldGetLayoutModifier(Widget widget)
XmTextFieldGetLayoutModifier は、ウィジェットに関連付けされたレンディションに関連して、現在のレイアウトオブジェクトに設定されている値を読み込みます。レイアウトオブジェクトの修飾子の値が簡易関数を用いて変更された場合、XmTextFieldGetLayoutModifier 関数は、変更された値だけでなくレイアウトオブジェクトに関するすべての状態を返します。
レイアウトオブジェクトの修飾子の値を文字列として返します。
この Text 関数はレイアウト修飾子の文字列を返します。返された文字列はレンディションに用いられるレイアウトオブジェクトの状態を示します。
#include <Xm/Text.h>String XmTextGetLayoutModifier(Widget widget)
XmTextGetLayoutModifier は、ウィジェットに関連付けされたレンディションに関連して、現在のレイアウトオブジェクトに設定されている値を読み込みます。レイアウトオブジェクトの修飾子の値が簡易関数を用いて変更された場合、XmTextGetLayoutModifier 関数は、変更された値だけでなくレイアウトオブジェクトに関するすべての状態を返します。
レイアウトオブジェクトの修飾子の値を文字列として返します。
XmText
この TextField 関数を設定することにより、レイアウト修飾子の値を設定して、レンディションに用いられるレイアウトオブジェクトの状態を変更することができます。
#include <Xm/TextF.h>void XmTextFieldSetLayoutModifier(Widget widget, string layout_modifier)
XmTextFieldSetLayoutModifier は、ウィジェットに関連付けされたレンディションに関連して、レイアウトオブジェクトの設定値を変更します。レイアウトオブジェクトの修飾子の値が簡易関数を用いて変更された場合、入力パラメータに指定された属性だけが変更されます。その他の属性は影響を受けません。
XmTextField
この Text 関数を設定することにより、レイアウト修飾子の値を設定して、レンディションに用いられるレイアウトオブジェクトの状態を変更することができます。
#include <Xm/Text.h>void XmTextSetLayoutModifier(Widget widget, string layout_modifier)
XmTextSetLayoutModifier は、ウィジェットに関連付けされたレンディションに関連して、レイアウトオブジェクトの設定値を変更します。レイアウトオブジェクトの修飾子の値が簡易関数を用いて変更された場合、入力パラメータに指定された属性だけが変更されます。その他の属性は影響を受けません。
XmText
#include <Xm/Xm.h>XmString XmStringDirectionCreate(direction)XmStringDirection direction
XmStringDirectionCreate は 1 個のコンポーネントを持つ複合文字列を、方向を指定して作成します。文字列の方向を指定するコンポーネントを持たない複合文字列 (XmString) については、XmNlayoutDirection リソースによりデフォルトのレンダリング方向が設定されています。つまり、XmNlayoutDirection リソースに適切な値を設定するだけで、レイアウト方向を設定することができます。特定の方向コンポーネントを持つ複合文字列を作成する必要はありません。アプリケーションにおいて XmString をレンダリングする場合、目的の文字列が XmStringDirection に方向を明示的に指定して作成されているかどうかを確認する必要があります。方向コンポーネントを持たない場合、アプリケーションは現在のウィジェットに対する XmNlayoutDirection リソースの値を確認して、その値を XmString のデフォルトのレンダリング方向として使用する必要があります。
XmRendition、XmDirection を参照してください。
UIL 引数名 |
引数名 |
---|---|
XmNlayoutAttrObject |
String |
XmNlayoutModifier |
String |
XmNrenditionTag |
String |
XmNalignment |
Integer |
XmNeditPolicy |
Integer |
複合文字列の方向は、左から右に記述される言語 (英語、スペイン語、フランス語、ドイツ語など) の場合と同様に、右から左に記述される言語 (ヘブライ語、アラビア語など) の場合にも利用可能なデータ構造で保管されます。Motif アプリケーションでは、VendorShell または MenuShell から XmNlayoutDirection リソースを使用してレイアウト方向を設定できます。また、プリミティブウィジェット (および Gadgets) も XmNlayoutDirection リソースを持ちます。
XmText ウィジェットに関しては、垂直方向も指定する必要があります。XmRIGHT_TO_LEFT に layoutDirection を設定すると、文字列の方向は右から左に設定されますが、カーソルは真下に移動します。垂直方向が重要で、上から下を希望する場合には、XmRIGHT_TO_LEFT_TOP_TO_BOTTOM を指定します。これにより、コンポーネントは希望通りまず右から左に、続いて上から下へレイアウトされます。
さらに、XmText および TextField ウィジェットの動作は、XmRendition の XmNalignment および XmNlayoutModifier リソースにも依存します。これらのリソースおよび XmNlayoutDirection は、Text ウィジェットのレイアウト動作を制御します。このことを下図の例を用いて説明します。
図で使用する入力文字列は次の通りです。
この図の左下のカラムに、XmNlayoutModifier の文字列 @ls orientation= に設定される値を示します。
図に示すとおり、XmNAlignment はレイアウト方向に関連してテキストを右フラッシュするか左フラッシュするかを指定します。一方、XmNlayoutModifier はテキストをセグメントに分割して、向きの値に従って左から右、または右から左に並べ直します。たとえば、XmlayoutDirection が XmRIGHT_TO_LEFT で XmNAlignment の値が XmALIGNMENTT_BEGINNING ならば、文字列は右フラッシュされます。
以下に示すプログラム例では「ArabicShaped」というタグを持つ Rendition を使用して、XmNlabelString のタイプが XmCHARSET_TEXT の XmLabel が作成されます。Rendition の作成には、「ar」(アラビア語ロケールのロケール名に対応) の XmNlayoutAttrObject が使用されます。また、その出力バッファには Numerals の値として NUMERALS_CONTEXTUAL を、ShapeCharset の値として「unicode-1」をそれぞれ指定するレイアウト修飾子文字列が使用されています。
ロケール固有のレイアウトモジュールにより、物理文字の出力バッファ内の入力テキストは 16 ビット Unicode 2.0 コードセットを用いて変換されます。下の例では入力テキストは ISO8859-6 で符号化されています。レイアウトロケールが明示的に指定されているため、ランタイムのロケール設定とは関係なく、このテキストは適切にレンダリングされます。
int n; Arg args[10]; Widget w; XmString labelString; XmRendition rendition; XmStringTag renditionTag; XmRenderTable renderTable; /* alef lam baa noon taa - iso8859-6 */ labelString = XmStringGenerate("¥307¥344¥310¥346¥312¥", NULL XmCHARSET_TEXT, "ArabicShaped"); w = XtVaCreateManagedWidget("a label", xmLabelWidgetClass, parent, XmNlabelString, labelString, XmNlabelType, XmSTRING, NULL); n = 0; XtSetArg(args[n], XmNfontName, "-*-*-medium-r-normal-*-24-*-*-*-*-*-*-*"); n++; XtSetArg(args[n], XmNfontType, XmFONT_IS_XOC); n++; XtSetArg(args[n], XmNlayoutAttrObject, "ar"); n++; XtSetArg(args[n], XmNlayoutModifier, "@ls numerals=:contextual, shapecharset=iso8859-6"); n++; renditionTag = (XmStringTag) "ArabicShaped"; rendition = XmRenditionCreate(w, renditionTag, argcs s, n); renderTable = XmRenderTableAddRenditions(NULL, &rendition, 1, XmREPLACE_MERGE); XtVaSetValues(w, XmNrenderTable, renderTable, NULL);
以下に示すプログラム例では、TextField ウィジェットと RenderTable が 1 個の Rendition により作成されます。疑似リソース XmNlayoutAttrObject と XmNlayoutModifier は両方とも未指定の状態になっているため、デフォルト値 NULL が使用されます。このことは Rendition に関連付けされた LayoutObject が存在する場合、その LayoutObject がデフォルトのロケールのものであることを示しています。
サンプルプログラムが正しく機能するためには、使用するロケールのコードセットが ISO 8859-6 で、ロケール固有のレイアウトモードが IMPLICIT_BASIC アルゴリズムをサポートしている必要があります。コード例では、Rendition の LayoutObject の ImplicitAlg の値が Rendition の XmNlayoutModifier の疑似リソース経由で変更されています。
int n; Arg args[10]; Widget w; XmRendition rendition; XmStringTag renditionTag; XmRenderTable renderTable; w = XmCreateTextField(parent, "text field", args, 0); n = 0; XtSetArg(args[n], XmNfontName, "-*-*-medium-r-normal-*-24-*-*-*-*-*-*-*"); n++; XtSetArg(args[n], XmNfontType, XmFONT_IS_XOC); n++; renditionTag = (XmStringTag) "ArabicShaped"; rendition = XmRenditionCreate(w, renditionTag, args, n); renderTable = XmRenderTableAddRenditions(NULL, &rendition, 1, XmREPLACE_MERGE); XtVaSetValues(w, XmNrenderTable, renderTable, NULL); .... n = 0; XtSetArg(args[n], XmNlayoutModifier, "@ls implicitalg=basic"); n++; XmRenditionUpdate(rendition, args, n);
XmDirection、XmText を参照してください。
レンディションおよびレンダーテーブルをリソースファイルに指定することができます。適切に国際化されたアプリケーションでは、この方法を使用することをお勧めします。レンダーテーブルがファイルとして指定される場合、プログラムの実行ファイルはロケールごとの特定の要求に依存しなくなるため、ロケールの要求に応じて簡単にカスタマイズを行うことができます。
レンダーテーブルをリソースファイルとして指定する場合、次の構文が用いられます。
resource_spec:[tag[,tag]*]
ここで tag には、レンディションの XmNtag リソースに適した文字列を指定します。
この行により、指定に従って 1 つまたは複数のレンディションを含む内部レンダーテーブルが作成されます。レンディションは指定されたタグに添付されます。
resource_spec[*|.] rendition[*|.]resource_name:value
以下の例では、XmRendition に関連付けられた CTL リソースのうち、リソースファイルを使用して設定できるものを紹介します。レイアウトオブジェクトを有効にするには、fontType が FONT_IS_XOC に設定されている必要があります。@ls を使って指定された layoutModifier はレンディションオブジェクトによりレイアウトオブジェクトに受け渡されます。
layoutModifier を使ってレイアウトオブジェクト上に設定可能なリソースの完全な一覧については、『CAE Specification: Portable Layout Services: Context-dependent and Directional Text』(The Open Group: Feb 1997; ISBN 1-85912-142-X; document number C616) を参照してください。
レンダーテーブルを作成するには、テーブルを構成するレンディションがアプリケーションプログラムにより少なくとも 1 個は作成されている必要があります。その名前が示すとおり、XmRenderTableAddRenditions 関数は新しいレンディションをレンダーテーブルに追加します。新しいレンダーテーブルを作成するには、既存のレンダーテーブル名の代わりに NULL を引数に指定して XmRenderTableAddRenditions() 関数を使用します。
以下に示すプログラム例では、XmNfontType を XmFONT_IS_XOC に設定して作成されたレンディションを使用してレンダーテーブルが作成されます。
int n; Arg args[10]; Widget w; XmString labelString; XmRendition rendition; XmStringTag renditionTag; XmRenderTable renderTable; /* alef lam baa noon taa - iso8859-6 */ labelString = XmStringGenerate("¥307¥344¥310¥346¥312¥", NULL XmCHARSET_TEXT, "ArabicShaped"); w = XtVaCreateManagedWidget("a label", xmLabelWidgetClass, parent, XmNlabelString, labelString, XmNlabelType, XmSTRING, NULL); n = 0; XtSetArg(args[n], XmNfontName, "-*-*-medium-r-normal-*-24-*-*-*-*-*-*-*"); n++; XtSetArg(args[n], XmNfontType, XmFONT_IS_XOC); n++; XtSetArg(args[n], XmNlayoutAttrObject, "ar"); n++; XtSetArg(args[n], XmNlayoutModifier, "@ls numerals=nominal:contextual, shapecharset=iso8859-6"); n++; renditionTag = (XmStringTag) "ArabicShaped"; rendition = XmRenditionCreate(w, renditionTag, args, n); renderTable = XmRenderTableAddRenditions(NULL, &rendition, 1, XmREPLACE); XtVaSetValues(w, XmNrenderTable, renderTable, NULL);
複合文字列内にタブ文字を用いてテキストの配置を制御できます。画面上でこれらの文字を解釈するために、ウィジェットはその複合文字列に対する有効なレンディションを参照して、タブストップのリストを検索します。ただし、動的なウィジェット (TextField および XmText) では、レンディションのタブリソースは使用されません。これらのウィジェットでは、式 8*(文字 0 の幅) によりタブの幅が計算されます。
タブは、表示される複合文字列の左マージンからの距離として測定されます。レイアウト方向が右から左の場合は、右マージンから測定されます。タブにより挿入される空白文字は、レイアウト方向の指定 (XmNlayoutDirection) に従ってテキストの右側または左側に挿入されます。どちら側に挿入されるかはテキストの方向 (たとえばアラビア語の場合右から左、英語の場合は左から右) には依存しません。
タブに続くテキストの位置は常にタブストップの位置に揃えられます。タブストップはウィジェットの始点から計算されます。この始点の位置は XmNlayoutDirection に依存します。タブの動作、およびテキストの方向性や XmNlayoutDirection との関連性について、図 10-1 に図示します。
この図で用いた入力は abc¥tdef¥tgh です。
一次セレクションには SELECT (マウスの左ボタン) を使用します。SELECT を押すと現在選択されている内容が選択解除され、ボタンが押された時点におけるカーソル位置に挿入カーソルとアンカーが移動します。SELECT を押しながらマウスをドラッグすると、アンカーの位置からポインタの位置までの間のテキストがすべて選択され、範囲外にあるすべてのテキストが選択解除されます。
選択されたテキストはリソース XmNeditPolicy に依存します。XmNeditPolicy は XmEDIT_LOGICAL または XmEDIT_VISUAL に設定できます。XmNeditPolicy が XmEDIT_LOGICAL に設定され、選択されたテキストが双方向ならば、選択されたテキストは個別のセグメントの集合体として表示されます。したがって、視覚的になめらかな表示にはなりません。これは、論理バッファ内のテキストが表示内容と 1 対 1 対応していないためです。
その結果、双方向テキストの論理文字の連続したバッファのレンダリング結果は、画面上でなめらかに連続した文字にはなりません。一方、XmNeditPolicy が XmEDIT_VISUAL に設定されると、表示上、選択されたテキストはなめらかになりますが、論理バッファ内では個別のセグメントとして保存されている可能性があります。したがって、双方向テキストに対して一連の選択、削除、挿入操作を同じカーソル位置で実行しても、結果が同じ文字列にならない場合があります。
マウスで実行可能な選択に関連した操作は、キーボードショートカットを使用して実行することもできます。テキストを選択するには Shift キーと矢印キーを組み合わせます。
選択されたテキストはリソース XmNeditPolicy に依存します。XmNeditPolicy は XmEDIT_LOGICAL または XmEDIT_VISUAL に設定できます。XmNeditPolicy が XmEDIT_LOGICAL に設定され、選択されたテキストが双方向ならば、選択されたテキストは個別のセグメントの集合体として表示されます。したがって、視覚的になめらかな表示にはなりません。これは、論理バッファ内のテキストが表示内容と 1 対 1 対応していないためです。その結果、双方向テキストの論理文字の連続したバッファのレンダリング結果は、画面上でなめらかに連続した文字にはなりません。
一方、XmNeditPolicy が XmEDIT_VISUAL に設定されると、選択されたテキストは表示上はなめらかになりますが、論理バッファ内では個別のセグメントとして保存されている可能性があります。
テキストはジオメトリに関連するいくつかのリソースを持ちます。
レンダーテーブル XmNrenderTable。ウィジェットがフォントまたはフォントセット、およびテキストを表示するその他の属性を選択する場合に使用
Text および Textfield ウィジェットが使用できるのは、XmNfontType などフォント関連のレンディションリソースだけです。また、XmNlayoutAttrObject などのレイアウトオブジェクトの属性 (通常はロケール識別子) を指定できます。さらに、XmRendition に関連付けられた XOC に関連付けられた Layout Object に受け渡されるレイアウト値を指定する XmNlayoutModifier も指定できます。
リソース XmNwordWrap。テキストがウィジェットよりも大きい場合に、ワードの境目で行を分割するかどうかを指定
ワードの境目で行を分割しても新しい行は挿入されません。アラビア語のような続け字で記述される言語では、ワードの長さがウィジェットよりも長ければ、そのワードは次の行に折り返されます。次の行の先頭の文字は、論理バッファ内の前の文字とは関係なく整形されます。
CTL 機能が組み込まれた新しい Motif ライブラリは /usr/dt/lib/libXm.so.4 に保管されています。libXm.so.3 をアプリケーションのリンク先に指定した場合、Complex Text Layout (CTL) は利用できません (アプリケーションのリンク先ライブラリを表示するには、ldd app_name と入力します)。既存のアプリケーションを移植して CTL に対応させるには、以下の手順に従います。
Makefile に -DSUN_CTL を追加します。このフラグは重要です (CTL をサポートするために必要なデータ構造が含まれています)。コンパイルの際に設定してください。
既存のアプリケーションを再コンパイルします。CTL をサポートする Motif ライブラリ libXm.so.4 が自動的にリンクされます。
以下の各リソースをアプリケーションのリソースファイルとして追加します。ロケールのレイアウトエンジンを起動するにはこれらのリソースが必要です。
マニュアルに添付されているサンプルアプリケーションを参照します。
fontName には、適切かつ利用可能なロケール名を指定します。
XmTextField または XmText のウィジェットにセルベースの文字の流れ (タイ語など) を使用するには、対応するウィジェットの変換を次のように設定します。詳細についてはマニュアルを参照してください。
XmText.translations: #override ¥n¥
<Key>osfRight:forward-cell() ¥n¥
<Key>osfLeft:backward-cell() ¥n¥
<Key>osfDelete:delete-next-cell() ¥n¥
<Key>osfBackSpace:delete-previous-cell() ¥n¥