Apple Developer Connection
高度な検索
Member Login ログイン | ご入会 ADC連絡先

Technical Note TN2026
MLTE (Multilingual Text Engine) に関するよくある質問とその答え

このテクニカルノートは、MLTE (Multilingual Text Engine) に関するよくある質問とその答えをまとめたものです。





入手方法と動作環境

Q:MLTE APIはどこで入手できますか?また、アップルはTextEditに代えてMLTEを利用するエディットテキストコントロールを作成するためのAPIについて言及していました。CreateEditUnicodeTextControlという名前のAPIだそうですが、このAPIはどこで入手できますか?

A:MLTE APIはMac OS X v10.0以降、Mac OS 8.6以降に対応したCarbonLibの全バージョン、およびMac OS 9.0以降に含まれています。

UnicodeエディットテキストコントロールはMac OS X v10.0以降に含まれています。UnicodeエディットテキストコントロールはCarbonLibには含まれていません。

先頭に戻る

ビューレクタングルとデスティネーションレクタングルの管理

Q:MLTEオブジェクトでビューレクタングルとデスティネーションレクタングルを設定、変更する方法は?

A:オブジェクトの作成時に、TXNNewObject関数によってビューレクタングルとデスティネーションレクタングルの両方が設定されます。値は入力パラメータに応じて次のように変わります。

a)iFrameがNULLの場合(ウインドウの場合)

オブジェクトの作成時にkTXNAlwaysWrapAtViewEdgeMaskフレームオプションが指定されていない場合は、ビューレクタングルにはウインドウの境界が、デスティネーションレクタングルにはデフォルト値が設定されます。CarbonLibとMac OS 9の場合は、現在選択されている用紙サイズ(「ページ設定」)がデフォルト値になります。Mac OS Xの場合は、デフォルト値は(今のところ)定数です。

kTXNAlwaysWrapAtViewEdgeMaskフレームオプションが指定されている場合は、ビューレクタングルにはウインドウの境界が、デスティネーションレクタングルにはウインドウの境界からスクロールバーの幅を除いた値が設定されます(スクロールバーが要求されていた場合)。

先頭に戻る

b)iFrameが有効なレクタングルへのポインタの場合(ペインの場合)

kTXNAlwaysWrapAtViewEdgeMaskが有効であっても無効であっても、初期の動作は同じです。ビューレクタングル(オブジェクト作成時にスクロールバーが要求されていた場合はスクロールバーも含む)には、入力レクタングルと同じ値が設定されます。デスティネーショレクタングルには、入力レクタングルからスクロールバーの幅を除いた値が設定されます(スクロールバーが要求されていた場合)。

では、MLTEクライアントでビューレクタングルとデスティネーションレクタングルの調節ができるようにするAPIについて説明しましょう。

ビューレクタングルだけを設定し、デスティネーションレクタングルは変更せずそのままにしておくというのが、TXNSetFrameBounds関数の標準的な動作です。しかし、kTXNAlwaysWrapAtViewEdgeMaskを利用している場合は、ビューレクタングルとデスティネーションレクタングルは同じ値になるように維持されます。結果的に両方のレクタングルの値が設定されることになります。

TXNResizeFrame関数はビューレクタングルとデスティネーションレクタングルの両方を設定します。ビューレクタングルの幅と高さには、それぞれ入力の幅と高さが設定されます。垂直スクロールバーが存在する場合は、デスティネーションレクタングルの幅には入力の幅からスクロールバーの幅を除いた値が設定されます。MTLEモデルではデスティネーションレクタングルの高さが無限大であると想定されているため、高さは変更されません。

TXNGetViewRect関数が現在のビューレクタングルを取得します。スクロールバー領域が存在する場合は、レクタングルの一部と見なされます。

今のところ、MLTEには現在のデスティネーションレクタングルを設定したり取得したりする関数はありません。しかし、ビューレクタングルやデスティネーションレクタングルを別の値に設定する必要がある場合は、TXNResizeFrame関数に続いてTXNSetFrameBoundsを呼び出すことによって、これを行うことができます。TXNResizeFrame関数はデスティネーションレクタングルとビューレクタングルの両方を設定し、TXNSetFrameBounds関数はビューレクタングルの境界を設定します。

では、kTXNAlwaysWrapAtViewEdgeMaskオプションを詳しく見ていきましょう。このオプションが指定されていると、ビューレクタングルとデスティネーションレクタングルは同じ値になるように維持されます(スクロールバーの分だけ、わずかに異なる値を取ります)。たとえば、このマスクを使用しているときにウインドウのサイズが変更されると、テキストのレイアウトが計算し直されます。これは、たとえばMLTEオブジェクトがウインドウの幅一杯に表示されていて、テキストが必ずウインドウの端で折り返されるようにしたい場合に便利です。

先頭に戻る

MLTEでQuartzを利用するには

Q:システムの他の部分と同じように、Mac OS Xでアンチエイリアス化されたテキストをMLTEにレンダリングさせたいと思います。MLTEはこの機能をサポートしていますか?

A:MLTEはMac OS X v10.0以降でQuartzのアンチエイリアス化されたテキストをサポートしています。これを行うには、クライアント側でCGコンテキストを作成し、TXNSetTXNObjectControls関数を利用してMLTEに渡します。Quartzによるレンダリングを有効にするサンプルコードを以下に示します。

リスト1:Quartzレンダリングの有効化

 TXNControlTag  controlTags[] = { kATSUCGContextTag };
 TXNControlData  controlData[1];
 CGContextRef  cgContext;

 if ( CreateCGContextForPort( aGrafPort, &cgContext ) == noErr )
 {

  controlData[0].uValue = (UInt32) cgContext;
  status = TXNSetTXNObjectControls(
    theMLTEObject,
    false,
    sizeof( controlTags ) / sizeof( TXNControlTag ),
    controlTags,
    controlData );
 }

先頭に戻る

カーソルの表示について

Q:MLTEオブジェクトにフォーカスが当たっていない場合は(TXNFocus(txnObject, false))、カーソルは点線として表示されます。別のテキストエンジンを使ったときは、MLTEオブジェクトにフォーカスが当たっていないときにはカーソルが表示されませんでした。MLTEでも同じようにする方法は?

A:Mac OS X v10.0以降、およびCarbonLib 1.2以降のMLTEには、オブジェクトにフォーカスが当たっていない場合のカーソルやテキスト選択の外観を柔軟に変更できるフレームオプションがいくつか用意されました。このフレームオプションは、TXNNewObject関数を使ってオブジェクトを作成すると設定されます。

フレームオプションkTXNDontDrawCaretWhenInactiveMaskを指定すると、テキストオブジェクトにフォーカスが当たっていないときにカーソルは描画されません。一方、テキストオブジェクトにフォーカスが当たっていないときにセレクト範囲(もしあれば)が描画されないようにするには、フレームオプションkTXNDontDrawSelectionWhenInactiveMaskを指定します。

MLTEオブジェクトの作成時にこれらのオプションを設定すると、オブジェクトにフォーカスが当たっていないときにカーソルは表示されません。

また、制御タグkTXNDrawCaretWhenInactiveTagkTXNDrawSelectionWhenInactiveTag、およびこれに対応する値kTXNDontDrawCaretWhenInactivekTXNDrawCaretWhenInactivekTXNDontDrawSelectionWhenInactivekTXNDrawSelectionWhenInactiveTXNSetTXNObjectControls関数に渡して利用できるようになりました。これらの制御タグと対応する値は、オブジェクトの作成後にアクティブでないキャレットとセレクト範囲(もしあれば)の見え方を調整するために利用できます。

先頭に戻る

テキストスタイル属性の設定

Q:現在のセレクト範囲の色、大きさ、スタイルを設定するには?

A:TXNSetTypeAttributes関数を使えば、1回の呼び出しで1つ以上のテキスト属性を設定できます。現在のセレクト範囲を太字で赤色の36ポイントに設定するコードの例を以下に示します。

リスト2:テキストスタイル属性の設定

 // タイプ属性データ構造体を作成
 RGBColor  fontColor = { 0xFFFF, 0, 0 };
 UInt32    fontSize = 36 << 16; // needs to be in Fixed format
 TXNTypeAttributes attributes[] = {
         { kTXNQDFontStyleAttribute, kTXNQDFontStyleAttributeSize, bold },
         { kTXNQDFontColorAttribute, kTXNQDFontColorAttributeSize, &fontColor },
         { kTXNQDFontSizeAttribute, kTXNQDFontSizeAttributeSize, fontSize }
 };

 // TXNSetTypeAttributesの呼び出し
 status = TXNSetTypeAttributes( myMLTEObject, 3, attributes,
      kTXNUseCurrentSelection,
      kTXNUseCurrentSelection );

ここではTXNSetTypeAttributes関数の呼び出しに対してメタオフセットkTXNUseCurrentSelectionを指定しています。しかし、有効なオフセットである限り、任意の範囲のオフセットを指定してこの関数を呼び出せます。また、この関数の呼び出し時に属性を1つずつ指定することにより、フォントスタイル、色、フォントサイズを個別に設定できます。

先頭に戻る

フォントの設定

Q:現在のセレクト範囲のフォントを設定するには?

A:まず、使いたいフォントのATSUFontIDを取得する必要があります。次に、TXNSetTypeAttributes関数を利用して、取得したIDをMLTEに渡します。たとえば、MLTEオブジェクト内の現在のセレクト範囲を「Apple Chancery」で表示するには、次のようにします。

リスト3:フォントの設定

 //ATSUIフォントIDの取得
 Str255 fontName = "\pApple Chancery";
 ATSUFontID fontID;

 status = ATSUFindFontFromName(
   (Ptr) fontName+1,
   (long) fontName[0],
   kFontFullName,
   kFontNoPlatform,
   kFontNoScript,
   kFontNoLanguage,
   &fontID );

 //TXNSetTypeAttributes関数を利用してATSUIフォントIDをMLTEへ渡す
 TXNTypeAttributes attributes[] =
   {kATSUFontTag, sizeof(ATSUFontID), {0}};

 attributes.data.dataValue = fontID;
 status = TXNSetTypeAttributes( myMLTEObject, 1, attributes,
   kTXNUseCurrentSelection,  kTXNUseCurrentSelection );

ATSUI APIに関する他の資料は、Apple Developer WebサイトのATSUI Referenceで入手できます。

先頭に戻る

フォントの取得

Q:MLTEで、任意のスタイルランで使われているフォントを知るには?

A:スタイルランで使われているATSUIフォントIDを知るには、TXNGetContinuousTypeAttributes関数を利用します。以下に例を示します。

リスト4:フォントの取得

 ATSUFontID fontID;
 TXNContinuousFlags continuousFlags;
 TXNTypeAttributes attributes[] =
   {kATSUFontTag, sizeof(ATSUFontID), {0}};

 TXNGetContinuousTypeAttributes( myMLTEObject,
   &continuousFlags, 1, attributes);

 fontID = attributes[0].data.dataValue;

先頭に戻る

スクロールバーのレンダリング

Q:現在、MLTEオブジェクトを作成しています(オブジェクトの初期のレクタングルが指定された状態です)。しかし、TXNResizeFrameを呼び出したときに、スクロールバーが正しくレンダリングされません。具体的にいえば、スクロールバーの内側には境界線がありますが、外側にはありません。また、スクロールバーの一番上に変更前のサイズの名残りのようなものがあります。何かアドバイスはありませんか?

A:ご質問の問題を解決するには、InvalWindowRect関数を呼び出し、MLTEオブジェクトが利用していた古いビューレクタングルを無効にする必要があります。TXNGetViewRectを使ってオブジェクトのビューレクタングルを取得すると、この関数から返されるレクタングルにはスクロールバーの外側の境界線は一切含まれません。したがって、この場合には、まずInsetRect(&myMLTEObjectViewRect, -1, -1)を呼び出して周囲全体を1ピクセル分大きくし、それからその拡大したレクタングルに対してInvalWindowRectを呼び出すようにします。

ペインオブジェクトでTXNSetFrameBoundsを利用する場合も同じ方法を用います。

先頭に戻る

Carbonアプリケーション

Q:MLTEを使うアプリケーションをCarbonに対応させようとしています。APIの呼び出しに違いはありますか?

A:Carbonアプリケーションでは、TXNTSMCheckは呼び出せません。これは、Carbonの場合には、TSM (Text Services Manager) が自動的に初期化されるためです。また、TXNIdleTXNKeydownを呼び出す必要もありません。Carbonの場合、MLTEはカーソルを点滅させるタイマをインストールするため、アプリケーションでTXNIdle関数を呼び出す必要はありません。また、TSMはキーダウンを直接MLTEのUnicodeForKeyEventハンドラに送るため、TXNObjectにフォーカスがあるとアプリケーションはキーダウンを受け取れません。

Mac OS X v10.0とCarbonLib 1.3では、MLTEのCarbonイベントハンドラをサポートするために、TXNCarbonEventInfoデータ構造体が用意されています。この機能の導入により、MLTEのCarbonアプリケーションはテキスト入力イベントのCarbonイベントモデルを十分に活用できるようになりました。

先頭に戻る

Carbonイベント

Q:MLTEでCarbonイベントのサポートを有効にするには?

A:デフォルトでは、MLTEはテキストの入力にApple Event Managerを利用します。しかし、TXNCarbonEventInfoデータ構造体が最近追加されたため、MLTEクライアントで、テキスト入力処理にMLTEがCarbonイベントを利用するように指定できます。MLTEオブジェクト用にMLTEがCarbonイベントをサポートするように設定するには、次のようにします。

  • イベントターゲットの辞書を作成します。

  • 独自のアクションキーマッピングコールバック関数を用意します(省略可能)。

  • MLTEに処理させたい各イベントに関する情報を渡し、TXNCarbonEventInfo構造体をインスタンス化します。

  • TXNSetTXNObjectControls関数を呼び出します。

テキスト入力イベント向けにMLTECarbonイベントハンドラを有効にするサンプルコードを以下に示します。

リスト5:MLTE Carbonイベントハンドラの有効化

 // 変数の宣言
 TXNControlTag  controlTags[] = { kTXNUseCarbonEvents };
 TXNControlData  controlData[1];
 TXNCarbonEventInfo carbonEventInfo;
 CFStringRef   keys[] = { kTXNTextInputHandlerKey };
 EventTargetRef  values[] =
      { GetWindowEventTarget( myWindowRef ) };
 // Carbonのテキスト入力イベントを処理するための
 // TXNCarbonEventInfoデータ構造体を初期化
 carbonEventInfo.useCarbonEvents = true;
 carbonEventInfo.filler = 0;
 carbonEventInfo.flags = kTXNNoAppleEventHandlersMask;
 carbonEventInfo.fDictionary =

 CFDictionaryCreate( kCFAllocatorDefault,
    (const void **) &keys,
    (const void **) &values,
    1,
    &kCFCopyStringDictionaryKeyCallBacks,
    NULL );

 controlData[0].uValue = (UInt32) &carbonEventInfo;

 // CarbonハンドラをインストールするようMLTEへ通知
 status = TXNSetTXNObjectControls(
   theMLTEObject,
   false,
   sizeof( controlTags ) / sizeof( TXNControlTag ),
   controlTags,
   controlData );

 // 辞書のリリース
 CFRelease( carbonEventInfo.fDictionary );

先頭に戻る

パフォーマンスに関するヒント

Q:TXNObjectの内容をクリアする最良の方法は?

A:MLTEオブジェクトの内容をクリアするには、NULLポインタを渡してTXNSetData関数を呼び出します。

Q:kTXNAlwaysWrapAtViewEdgeBitを無効にしています。TXNResizeFrameTXNSetFrameBoundsと同程度の処理速度が期待できますか?

A:kTXNAlwaysWrapAtViewEdgeBitが無効の場合、TXNResizeFrameTXNSetFrameBoundsほどの処理速度にはなりません。TXNResizeFrameにはTXNSetFrameBoundsが行わないテキストの再レイアウトが伴うため、処理速度に違いが出ます。TXNResizeFrameはビューレクタングルとデスティネーションレクタングルの両方を設定するため、テキストの再レイアウトが生じます。これに対して、TXNSetFrameBoundsはビューレクタングルの境界だけを設定するため、テキストの再レイアウトは不要です。

kTXNAlwaysWrapAtViewEdgeBitTXNResizeFrameには何もしません。TXNResizeFrameを呼び出すと、(垂直スクロールバーがあれば、その分を除いた)ビューレクタングルの端でテキストが折り返されるように、ビューレクタングルとデスティネーションレクタングルがリセットされます。

先頭に戻る

ドキュメント改訂履歴

日付メモ
2005-09-12TXNSetFrameBoundsとTXNResizeFrameの使用に関する正しくない文を修正。
2001-07-11MLTE (Multilingual Text Engine) についてよくある質問を掲載。

掲載日: 2005-09-12




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.