レイヤーが文字のサイズとまったく同じになるように、CATextLayer で文字を描画する際に問題があります。
以下のコードを使用して、文字列内の文字に対応するグリフのサイズを取得します。現時点では、分音符号を無視しているため、グリフと文字の間には 1 対 1 の相関関係があると想定しています。
サイズ 128pt の Helvetica フォントのいくつかの文字のバウンディング ボックスの値も取得します。
Character | x | y | width | height |
B | 9.4 | 0.0 | 70.8 | 91.8 |
y | 1.3 | -27.4 | 61.2 | 96.0 |
座標を表す座標系の原点がどこにあるのかわかりません。(0,0) が一番左にあり、フォントのベースラインに垂直に配置されていると想定しています。そのため、'y' の y の値は負になります。
このコードを使用して、大文字の B のサイズを計算し、それに応じて CATextLayer のサイズを変更しています。
- (CATextLayer *) testTextLayer
{
CATextLayer *l = [CATextLayer layer];
l.string = @"B";
NSUInteger len = [l.string length];
l.fontSize =128.f;
CGColorRef blackColor = CGColorCreateGenericGray(0.f, 1.f);
l.foregroundColor = blackColor;
CGColorRelease(blackColor);
// need to set CGFont explicitly to convert font property to a CGFontRef
CGFontRef layerFont = CGFontCreateWithFontName((CFStringRef)@"Helvetica");
l.font = layerFont;
// get characters from NSString
UniChar *characters = (UniChar *)malloc(sizeof(UniChar)*len);
CFStringGetCharacters((__bridge CFStringRef)l.string, CFRangeMake(0, [l.string length]), characters);
// Get CTFontRef from CGFontRef
CTFontRef coreTextFont = CTFontCreateWithGraphicsFont(layerFont, l.fontSize, NULL, NULL);
// allocate glyphs and bounding box arrays for holding the result
// assuming that each character is only one glyph, which is wrong
CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph)*len);
CTFontGetGlyphsForCharacters(coreTextFont, characters, glyphs, len);
// get bounding boxes for glyphs
CGRect *bb = (CGRect *)malloc(sizeof(CGRect)*len);
CTFontGetBoundingRectsForGlyphs(coreTextFont, kCTFontDefaultOrientation, glyphs, bb, len);
CFRelease(coreTextFont);
l.position = CGPointMake(200.f, 100.f);
l.bounds = bb[0];
l.backgroundColor = CGColorCreateGenericRGB(0.f, .5f, .9f, 1.f);
free(characters);
free(glyphs);
free(bb);
return l;
}
これは、上記のコードから取得した結果です。サイズは正しいように見えますが、キャラクターの周りに何らかのパディングが行われています。
今私の質問
- グリフのバウンディングボックスの起源の仮定は正しいですか?
- このパディングなしで、レイヤーにきちんと収まるように文字を描くにはどうすればよいでしょうか? あるいは、このパディングをどのように制御できますか?
多分私はここで明らかな点を見逃しています。レイヤーのサイズとフォントを設定した後、定義された方法でキャラクターの周りにレイヤーをシュリンクラップする方法はありますか(CSSのようにオプションのパディングを使用することを意味します)?