#sizeWithAttributes
sizeWithAttributes
は、正しいサイズを取得できないケースがあります。
文字列に、指定フォントに無いものが含まれていれば、
sizeWithAttributes
は正しいサイズを取得出来ません。
例えば、等倍フォントである「Courier」は日本語が含まれていません。
フォントに「Courier」を指定し、文字列に日本語が含まれていれば、sizeWithAttributes
は本来のサイズを返しません。
iOSでは、足りない分は他フォントで代用、文字が表示されない事は無いので、
一見困ることはないのですが、上記の様な落とし穴に注意してください。
CoreTextならば、このような場合でも正しいサイズが取得できます。
NSString *text = @"チ";
// 文字装飾
NSMutableDictionary *dictAttr = [NSMutableDictionary dictionary];
[dictAttr setObject:[UIFont fontWithName:@"Courier" size:64.0] forKey:NSFontAttributeName];
/* ********************
* sizeWithAttributesでサイズ取得
******************** */
// サイズ取得
CGSize sizeFont = [text sizeWithAttributes:dictAttr];
// ログ出力
NSLog(@"sizeWith~:%@", NSStringFromCGSize(sizeFont));
/* ********************
* CoreTextでサイズ取得
******************** */
// 装飾文字列の生成
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:text attributes:dictAttr];
//フレームセッターの作成
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attrStr);
// サイズ取得
CGSize contentSize = CTFramesetterSuggestFrameSizeWithConstraints(
framesetter,
CFRangeMake(0, attrStr.length),
nil,
CGSizeMake(200, 200),
nil);
// ログ出力
NSLog(@"CoreText:%@", NSStringFromCGSize(contentSize));
sizeWith~:{64, 64}
CoreText:{64, 71}
このように、sizeWithAttributesでは縦幅が小さくなっています。
#drawInRect
drawInRectでも、上記に起因すると思われる問題が見られます。
drawInRectは、sizeWithAttributesと同じ認識を元に、描画の原点としている?
CGRect rectImage = CGRectMake(0, 0, 96.0, 96.0);
// 画像処理開始
UIGraphicsBeginImageContextWithOptions(rectImage.size, NO, 0.0);
// テキストの描画
[text drawInRect:rectImage withAttributes:dictAttr];
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
// 画像処理終了
UIGraphicsEndImageContext();
64x64に対して96x96の十分な余裕を持たせても、"チ"の上部がわずかに欠けてしまっています。
本来64x71のところ、
drawInRect
が64x64と誤認している為、原点がズレてしまっていると思われます。
drawInRect
のy軸を少しズラすと、上部も描画されます
#まとめ
日本語が含まれないフォントの使用は、それほど珍しくないように思います。
その都度、CoreTextを意識しないといけないのは少々面倒な話ですね。