iOSで行間調整、カーニングするメモ

UILabelの行間、カーニング調整できないクソ仕様に悶絶したので代替手段としてCoreTextを調べてみたメモ。

・もろもろパラメータ設定したNSAttributedStringを用意する。指定できるパラメータはCoreText.framework内CTStringAttributes.hを参照。

・CTFramesetterCreateWithAttributedString(CFAttributedString*)でCTFramesetterRef取得する。

・CoreFoundationとObjective-Cのデータ型はだいたい互換性があるらしく、引数がCF~のとこに、同名のNS~を(CF~)NS~みたいにキャストしてつっこめれる。

・CGPathCreateMutable()でCGMutablePathRef取得する。

・CGPathAddRect(CGMutablePathRef, NULL, self.bounds)で描画範囲を設定。

・取得したCTFramesetterRefとCGMutablePathRefからCTFramesetterCreateFrame(CTFramesetterRef, CFRange, CGPathRef, NULL)を使ってCTFrameRefを作る。

・UIViewのdrawRect:(CGRect)rect内でUIGraphicsGetCurrentContext()使ってCGContextRef取得。

・CTFrameDraw(CTFrameRef, CGContextRef)でテキスト描画。

・UIViewとCoreGraphicsで座標系が違うので、
CGContextTranslateCTM(CGContextRef, 0, self.bounds.size.height);
CGContextScaleCTM(CGContextRef, 1, -1);
で上下反転させておく。

CoreFoundationとかガチのC言語な上、手続きがめんどすぎるのでよっぽどのことがない限りUIWebViewで描画した方がよい。
あとCoreTextの日本語資料少な過ぎで死ぬ。

参考:
Core Text Programming Guide: Introduction
Text Layout With Core Text
CoreText.framework – iPhone Development Wiki