Core Text の概観
Core Text は、テキストのレイアウトとフォントの処理を行う高度で低レベルの技術です。Core Text は、Quartz とも呼ばれる Core Graphics(CG) で直接動作し、Quartz は、OS X と iOS の最低レベルで 2 次元イメージングを処理する高速グラフィックスレンダリングエンジンです。
Core Text は、上位レベルのフレームワークが提供するテキストレイアウトとフォントのサポートと、Quartz がすべてのテキストとフォントのフレームワークに提供する低レベルの機能を仲介します。Quartz フレームワークは、グリフとその位置に作用します。Core Text は、文字のフォントへのマッピング方法を認識し、Quartz を呼び出してテキストをレンダリングする前に、スタイル、フォントメトリック、およびその他の属性に関する情報を考慮に入れます。Quartz は根本的なレベルで描かれたグリフを得る唯一の方法であり、Core Text は Quartz が直接使用できる形式のデータをすべて提供しているため、高性能なテキストレンダリングが可能です。
Core Text は、C を基礎としたプラットフォーム中立の API
Core Text API は iOS と OS X でほぼ同じですが、OS X バージョンでは、可変フォントコレクションを含む豊富なフォント管理 API を提供しています。ただし、プラットフォーム間でコードを移植する際に考慮する必要がある UIKit と AppKit には違いがあります。たとえば、Core Text で生成したグリフをレンダリングするには、Quartz グラフィックコンテキストが必要で、各プラットフォームでグラフィックコンテキストが異なるようにしなければなりません。iOS で描画するビューは、iOS では UIView サブクラスで、OS X では NSView サブクラスです。そして、CGRect オブジェクトは UIView の drawRect: メソッドに渡され、drawRect: メソッドの OS X バージョンは NSRect オブジェクトに渡される事に注意が必要です。(OS X では NSRectToCGRect 関数を使用して、渡された NSRect オブジェクトを Core Text 関数パラメータとして必要な CGRect オブジェクトに変換できます)。
UIView 関数の UIGraphicsGetCurrentContext によって返されるグラフィックコンテキストは、変更されていない Quartz グラフィックコンテキスト(つまり、UIView によって返されたコンテキストの原点が左上隅です) に相対的に反転されるため、iOS でグラフィックコンテキストを再反転しなければならず、このテクニックのコード例については リスト 2-1 を参照してください。
Core Text は可能な限りシステムデータ型とサービスを使用しているので、OS X と iOS の両方の他のコアフレームワークに関連する同じ規約を使用して下さい。たとえば、Core Text では、多くの入出力パラメータに Core Foundation オブジェクトを使用するため、Core Foundation コレクションクラスにそれらを格納できます。CGPath オブジェクトなどの Core Text によって処理される他のオブジェクトは、Core Graphics フレームワークによって提供されます。
Core Text オブジェクトは C 言語の不透明型
OS X と iOS の低レベルライブラリの多くは、速度と簡潔さのためにプレーンな C で書かれています。Core Text を使用する場合、Objective-C クラスおよびメソッドの代わりに CTFramesetterCreateWithAttributedString や CTFramesetterCreateFrame などの C 関数のセットを使用して下さい。
Core Text の不透明型
Core Text レイアウトエンジンは、属性付き文字列(CFAttributedStringRef) やグラフィックパス(CGPathRef) で動作することがよくあります。属性付き文字列オブジェクトは、表示されたテキストを裏付ける文字列をカプセル化し、文字列内の文字の書体的な側面(フォントや色など) を定義するプロパティ(または「属性」) を含みます。Core Text の植字メカニズムは、属性付き文字列内の情報を使用して文字からグリフへの変換を実行します。
グラフィックパスは、テキストのフレームの形状を定義します。OS X v10.7 および iOS 3.2 以降では、パスは長方形でなくできます。
CFAttributedString 参照型である、CFAttributedStringRef は、Foundation の対応する、NSAttributedString と通話無料でブリッジされています。つまり、Core Foundation 型は、関数またはメソッド呼び出しで、ブリッジされた Foundation オブジェクトと交換可能です。したがって、NSAttributedString * パラメータを参照するメソッドでは、CFAttributedStringRef を渡すことができ、CFAttributedStringRef パラメータを参照する関数では、NSAttributedString インスタンスを渡すことができます。(コンパイラの警告を抑制するために、ある型を他の型にキャストする必要があるかもしれません)。これは、NSAttributedString の具象サブクラスにも当てはまります。
属性は、同じ属性を共有する範囲でグループ化された文字列の文字のスタイル特性を定義するキー値のペアです。属性自体は、属性付き文字列に渡され、CFDictionary オブジェクトを使用してそれらから取得されます。グリフラン(CTRun オブジェクト) にスタイルを適用するには、適用する属性を保持する CFDictionary オブジェクトを作成し、属性付きの文字列を作成し、その辞書をパラメータとして渡します。または、既存の CFMutableAttributedString オブジェクトに属性を適用することもできます。CFDictionaryRef と NSDictionary は通話無料でブリッジされていますが、辞書に格納されている個々の属性オブジェクトはそうでないかもしれません。
実行時の Core Text オブジェクトは、図 1-1 に示すように、階層を形成します。この階層の最上部にはフレームセッターオブジェクト(CTFramesetterRef) があります。属性文字列とグラフィックスパスを入力として、フレームセッターは 1 つ以上のテキストフレーム(CTFrameRef) を生成します。各 CTFrame オブジェクトは段落を表します。
図 1-1 Core Text レイアウトエンジンのアーキテクチャ
フレームを生成するために、フレームセッターはタイプセッターオブジェクト(CTTypesetterRef) を呼び出します。フレームセッターは、フレーム内にテキストを配置するため、整列、タブストップ、行間、インデント、及び改行などの属性を含む段落スタイルを適用します。タイプセッターは、属性付き文字列内の文字をグリフに変換し、そのグリフをテキストフレームを満たす行に収めます。
各 CTFrame オブジェクトには、段落の行(CTLine) オブジェクトが含まれています。各行オブジェクトは 1 行のテキストを表します。CTFrame オブジェクトには、長い CTLine オブジェクトが 1 つだけ含まれていたり、一連の行が含まれている場合があります。Line オブジェクトは、フレームセッティング操作中にタイプセッターによって作成され、フレームと同様にグラフィックスコンテキストに直接描画できます。
各 CTLine オブジェクトには、グリフラン(CTRun) オブジェクトの配列が含まれています。グリフランは、同じ属性と方向を共有する一連の連続したグリフです。タイプセッターは、文字列、属性、およびフォントオブジェクトから行を生成するときに、グリフランを作成します。これは、行が 1 つ以上のグリフランで構築されることを意味します。ほとんどのクライアントはグリフランと直接対話する必要はありませんが、グリフランは必要に応じてグラフィックコンテキストに自分自身を描画できます。
フォントオブジェクト
フォントは、グリフ同士の相対的な配置を支援し、グラフィックスコンテキストで描画するときに現在のフォントを設定するために使用されます。Core Text フォントの不透明タイプ CTFont は、多くの情報をカプセル化する特定のフォントインスタンスです。参照型の CTFontRef は、iOS の UIFont と OS X の NSFont との無料通話でブリッジされています。CTFont オブジェクトを作成するときは、通常、ポイントのサイズと変換行列を指定して(またはデフォルトを使用して)、フォントインスタンスに固有の特性を与えます。次に、文字オブジェクトからグリフへのマッピング、コード化、フォントメトリックデータ、グリフデータや、他の物の間のものなどその特定のポイントサイズでのフォントに関する多くの種類の情報をフォントオブジェクトに問い合わせることができます。フォントメトリックは、上昇、下降、先行、頂点の高さ、x の高さなどのパラメータです。グリフデータには、境界の長方形やグリフの前進などのパラメータが含まれます。
Core Text フォントオブジェクトは不変であるため、複数の操作、作業キュー、またはスレッドで同時に使用できます。フォントオブジェクトを作成する方法はたくさんあります。推奨されるメソッドは、 CTFontCreateWithFontDescriptor を使用するフォント記述子からのものです。また、何を始める必要があるかに応じて、いくつかの変換 API を使用することもできます。たとえば、書体の PostScript 名(CTFontCreateWithName) または Core Graphics フォント参照(CTFontCreateWithGraphicsFont) を使用できます。CTFontCreateUIFontForLanguage もあります。これは、使用しているローカリゼーションのアプリケーションのユーザーインターフェイスフォントの参照を作成します。
Core Text フォント参照は、フォントカスケードという洗練された自動フォント置換メカニズムを提供します。これは、フォント特性を考慮しながら欠落したフォントを置換するための適切なフォントを選択します。フォントカスケードは、カスケードリストに基づいており、カスケードリストは、順序付きフォント記述子の配列です。システムのデフォルトのカスケードリスト (ユーザーの言語設定と現在のフォントに基づく多態型) と、フォント作成時に指定されたフォントカスケードリストがあります。フォント記述子の情報を使用して、カスケーディングメカニズムは、スタイルと、一致する文字に応じてフォントを一致させることができます。CTFontCreateForString 関数はカスケードリストを使用して、指定された文字列をコード化するための適切なフォントを選択します。フォントカスケードリストを指定および取得するには、kCTFontCascadeListAttribute プロパティを使用して下さい。
フォント記述子
CTFontDescriptor の不透明型で表されるフォント記述子は、属性の辞書からフォントを完全に記述する仕組みと、新しいフォントを構築するための使いやすいフォントマッチング機能を提供します。フォント記述子からフォントオブジェクトを作成し、フォントオブジェクトから記述子を取得し、記述子を変更して新しいフォントオブジェクトを作成することができます。たとえば、一族の名前や重さなどのフォント記述子を作成してフォントを部分的に記述し、システム上の指定された特性に一致するすべてのフォントを見つけることができます。CTFontDescriptorRef 型は、iOS の UIFontDescriptor と OS X の NSFontDescriptor に通話無料でブリッジされています。
複雑な変換行列を扱う代わりに、PostScript 名、フォントファミリやスタイル、CTFontDescriptor オブジェクトとしての特性(太字や斜体) などのプロパティを含むフォント属性の辞書を作成できます。フォント記述子を使用すると、CTFont オブジェクトを作成できます。フォント記述子は、シリアル化してドキュメントに保存し、フォントの永続性を提供することができます。図 1-2 に、フォント記述子を使用して特定のフォントインスタンスを作成するフォントシステムを示します。
図 1-2 フォント記述子からフォントを作成
フォント記述子は、フォントシステムへの照会として考えることができます。不完全な仕様を持つフォント記述子を作成することができます。つまり、属性辞書に 1 つまたは少数の値を指定すると、使用可能なフォントの中から最も適切なフォントをシステムは選択します。たとえば、標準の字面(標準、太字、斜体、太字イタリック) のファミリ名の記述子を使用して照会(query) を作成した場合、ファミリ内のすべての字面に一致する特性は指定されませんが、特性辞書を kCTFontTraitBold の kCTFontTraitsAttribute で指定すると、結果はファミリ全体から大胆な特性を満たすメンバーにさらに絞り込まれます。システムは、CTFontDescriptorCreateMatchingFontDescriptors を使用して照会に一致するフォント記述子の完全なリストを提供できます。
iOS 6.0 以降では、アプリは、CTFontDescriptorMatchFontDescriptorsWithProgressHandler 関数を使用してインストールされていない使用可能なフォントをダウンロードできます。この方法でダウンロードされたフォントは永続的にインストールされず、特定の状況下でフォントをシステムが削除することがあります。ダウンロード可能なフォントは、iOS 6 : フォントリスト の"追加情報" と iOS 7:フォントリスト にリストされています。DownloadFont(iOS デベロッパーライブラリ内) は、ダウンロードの技法を示しています。OS X では利用可能なすべてのフォントがシステムにインストールされているため、オンデマンドでフォントをダウンロードする必要はありません。
フォントコレクション
フォントコレクションは、単一のオブジェクトとして扱われるフォント記述子のグループです。フォントコレクションは、CTFontCollection の不透明型で表されます。フォントコレクションは、フォント列挙、グローバルおよびカスタムフォントコレクションへのアクセス、およびコレクションを構成するフォント記述子へのアクセスの機能を提供します。たとえば、CTFontCollectionCreateFromAvailableFonts を呼び出して、システムで使用可能なすべてのフォントのフォントコレクションを作成し、そのコレクションを使用してすべてのメンバーのフォント記述子の配列を取得できます。
前の章 次の章