CATextLayer中不需要的填充

时间:2012-05-06 20:06:32

标签: cocoa core-animation core-text

我遇到了在CATextLayer中绘制角色的问题,这样该图层就是角色的大小。

我使用下面的代码来获取字符串中字符对应的字形大小。目前我忽略了diacretics,所以我假设字形和字符之间存在一对一的关联。

对于大小为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;
}

这是我从上面的代码得到的结果。在我看来,尺寸是正确的,但在角色周围会发生某种填充。

Result of the B on a CATextLayer

现在我的问题

  1. 我是否正确假设了字形的边界框的起源?
  2. 如何在没有这个填充的情况下绘制字母以使其整齐地嵌入图层中?或者,如何控制此填充?
  3. 也许我在这里错过了一个明显的观点。现在有没有设置图层的大小和字体以缩小以定义的方式围绕字符包裹图层(意味着使用可选的填充,有点像CSS)?


2 个答案:

答案 0 :(得分:3)

如何使用CGPath从字形创建CTFontCreatePathForGlyph,然后使用CGPathGetBoundingBox获取其边界框?

另一种方法是以某种方式创建CTRun并使用CTRunGetImageBounds函数,该函数也返回一个“紧”边界框,但这可能需要比上述方法更多的代码行,而且你' d需要有图形上下文。

答案 1 :(得分:1)

我认为这与字母周围的内置空间有关。如果你在一行中组合字形,它们的边界框通常包括一些空间作为一般间距。然后使用字距调整表对这些进行优化。

是的,提取实际的bezier路径是获得紧密边界框的一种非常好的方法。我已经这么做了多年,虽然我没有使用CATextLayers的经验。