一般的なフォント操作
この章では、一般的なフォント処理操作について説明し、Core Text を使用してそれらをコード化する方法を示します。これらの操作は、iOS と OS X で同じです。この章では、以下のコードリストでの操作について説明します。
フォント記述子の作成
リスト 3-1 の関数の例は、PostScript フォント名とポイントサイズを指定するパラメータ値からフォント記述子を作成します。
リスト 3-1 名前とポイントサイズからフォント記述子を作成する
CTFontDescriptorRef CreateFontDescriptorFromName(CFStringRef postScriptName, CGFloat size) { return CTFontDescriptorCreateWithNameAndSize(postScriptName, size); }
リスト 3-2 の関数の例は、フォントファミリ名とフォント特性からフォント記述子を作成します。
リスト 3-2 ファミリと特性からフォント記述子を作成する
NSString* familyName = @"Papyrus"; CTFontSymbolicTraits symbolicTraits = kCTFontTraitCondensed; CGFloat size = 24.0; NSMutableDictionary* attributes = [NSMutableDictionary dictionary]; [attributes setObject:familyName forKey:(id)kCTFontFamilyNameAttribute]; // The attributes dictionary contains another dictionary, the traits dictionary, // which in this example specifies only the symbolic traits. NSMutableDictionary* traits = [NSMutableDictionary dictionary]; [traits setObject:[NSNumber numberWithUnsignedInt:symbolicTraits] forKey:(id)kCTFontSymbolicTrait]; [attributes setObject:traits forKey:(id)kCTFontTraitsAttribute]; [attributes setObject:[NSNumber numberWithFloat:size] forKey:(id)kCTFontSizeAttribute]; CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)attributes); CFRelease(descriptor);
フォント記述子からフォントを作成
リスト 3-3 は、フォント記述子を作成しそれでフォントを作成する方法を示しています。 CTFontCreateWithFontDescriptor を呼び出す時は、通常、matrix パラメータに NULL を渡してデフォルトの(高等変換) 行列を指定します。CTFontCreateWithFontDescriptor の size と matrix(2 番目と 3 番目の) パラメータは、指定されている限り、フォント記述子で指定されたものを上書きします(size は 0.0、matrix は NULL)。
リスト 3-3 フォント記述子からフォントを作成
NSDictionary *fontAttributes = [NSDictionary dictionaryWithObjectsAndKeys: @"Courier", (NSString *)kCTFontFamilyNameAttribute, @"Bold", (NSString *)kCTFontStyleNameAttribute, [NSNumber numberWithFloat:16.0], (NSString *)kCTFontSizeAttribute, nil]; // Create a descriptor. CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes); // Create a font using the descriptor. CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL); CFRelease(descriptor);
関連したフォントの作成
既存のフォントを関連したフォントまたは類似のフォントに変換すると便利なことがよくあります。リスト 3-4 の関数の例は、関数呼び出しで渡されたブール値パラメータの値に基づいて、フォントを太字または太字でないフォントにする方法を示しています。現在のフォントファミリに要求されたスタイルがない場合、関数は NULL を返します。
リスト 3-4 フォントの形質を変える
CTFontRef CreateBoldFont(CTFontRef font, Boolean makeBold) { CTFontSymbolicTraits desiredTrait = 0; CTFontSymbolicTraits traitMask; // If requesting that the font be bold, set the desired trait // to be bold. if (makeBold) desiredTrait = kCTFontBoldTrait; // Mask off the bold trait to indicate that it is the only trait // to be modified. As CTFontSymbolicTraits is a bit field, // could change multiple traits if desired. traitMask = kCTFontBoldTrait; // Create a copy of the original font with the masked trait set to the // desired value. If the font family does not have the appropriate style, // returns NULL. return CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, desiredTrait, traitMask); }
リスト 3-5 の関数の例は、与えられたフォントを別のフォントファミリの類似のフォントに変換し、可能であれば特質を保持します。これは NULL を返すことがあります。size パラメータに 0.0 を渡し、matrix パラメータに NULL を渡すと、元のフォントのサイズが保持されます。
リスト 3-5 フォントを別のファミリに変換する
CTFontRef CreateFontConvertedToFamily(CTFontRef font, CFStringRef family) { // Create a copy of the original font with the new family. This call // attempts to preserve traits, and may return NULL if that is not possible. // Pass in 0.0 and NULL for size and matrix to preserve the values from // the original font. return CTFontCreateCopyWithFamily(font, 0.0, NULL, family); }
フォントのシリアル化
リスト 3-6 の関数の例は、文書に埋め込むことができるフォントをシリアル化する XML データを作成する方法を示しています。あるいは、NSArchiver を使用することができればより良いでしょう。これはこの作業を実行する単なる 1 つの方法ですが、後で正確なフォントを再作成するために必要なフォントのすべてのデータを保持します。
リスト 3-6 フォントのシリアル化
CFDataRef CreateFlattenedFontData(CTFontRef font) { CFDataRef result = NULL; CTFontDescriptorRef descriptor; CFDictionaryRef attributes; // Get the font descriptor for the font. descriptor = CTFontCopyFontDescriptor(font); if (descriptor != NULL) { // Get the font attributes from the descriptor. This should be enough // information to recreate the descriptor and the font later. attributes = CTFontDescriptorCopyAttributes(descriptor); if (attributes != NULL) { // If attributes are a valid property list, directly flatten // the property list. Otherwise we may need to analyze the attributes // and remove or manually convert them to serializable forms. // This is left as an exercise for the reader. if (CFPropertyListIsValid(attributes, kCFPropertyListXMLFormat_v1_0)) { result = CFPropertyListCreateXMLData(kCFAllocatorDefault, attributes); } } } return result; }
シリアル化したデータからフォントを作成
リスト 3-7 の関数の例は、フラット化された XML データからフォントリファレンスを作成する方法を示しています。これは、フォント属性を非平坦化し、それらの属性を使用してフォントを作成する方法を示します。
リスト 3-7 シリアル化したデータからフォントを作成
CTFontRef CreateFontFromFlattenedFontData(CFDataRef iData) { CTFontRef font = NULL; CFDictionaryRef attributes; CTFontDescriptorRef descriptor; // Create our font attributes from the property list. // For simplicity, this example creates an immutable object. // If you needed to massage or convert certain attributes // from their serializable form to the Core Text usable form, // do it here. attributes = (CFDictionaryRef)CFPropertyListCreateFromXMLData( kCFAllocatorDefault, iData, kCFPropertyListImmutable, NULL); if (attributes != NULL) { // Create the font descriptor from the attributes. descriptor = CTFontDescriptorCreateWithAttributes(attributes); if (descriptor != NULL) { // Create the font from the font descriptor. This sample uses // 0.0 and NULL for the size and matrix parameters. This // causes the font to be created with the size and/or matrix // that exist in the descriptor, if present. Otherwise default // values are used. font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL); } } return font; }
カーニングの変更
リガチャーとカーニングはデフォルトで有効です。無効にするには、kCTKernAttributeName 属性を 0 に設定します。リスト 3-8 では、最初に描かれた数文字のカーンサイズを大きな数値に設定します。
リスト 3-8 カーニングの設定
// Set the color of the first 13 characters to red // using a previously defined red CGColor object. CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 13), kCTForegroundColorAttributeName, red); // Set kerning between the first 18 chars to be 20 CGFloat otherNum = 20; CFNumberRef otherCFNum = CFNumberCreate(NULL, kCFNumberCGFloatType, &otherNum); CFAttributedStringSetAttribute(attrString, CFRangeMake(0,18), kCTKernAttributeName, otherCFNum);
文字用のグリフの取得
リスト 3-9 は、文字列内の文字用のグリフを単一のフォントで取得する方法を示しています。たいていの場合、CTLine オブジェクトを使用してこの情報を取得する必要があります。1 つのフォントは文字列全体をコード化しない可能性があるからです。さらに、単純な文字からグリフへのマッピングでは、複雑なスクリプトの正しい外観が得られません。この単純なグリフマッピングでは、フォントに特有な Unicode 文字を表示しようとしている場合に適しています。
リスト 3-9 文字用のグリフの取得
void GetGlyphsForCharacters(CTFontRef font, CFStringRef string) { // Get the string length. CFIndex count = CFStringGetLength(string); // Allocate our buffers for characters and glyphs. UniChar *characters = (UniChar *)malloc(sizeof(UniChar) * count); CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * count); // Get the characters from the string. CFStringGetCharacters(string, CFRangeMake(0, count), characters); // Get the glyphs for the characters. CTFontGetGlyphsForCharacters(font, characters, glyphs, count); // Do something with the glyphs here. Characters not mapped by this font will be zero. // ... // Free the buffers free(characters); free(glyphs); }
前の章 次の章