Cocoa CATextLayer中不需要的填充
我在CATextLayer中绘制角色时遇到了一个问题,使得该层正好是角色的大小 我使用下面的代码来获得与字符串中的字符对应的glyph的大小。目前,我忽略了历时性,因此我假设字形和字符之间存在一对一的相关性 对于大小为128pt的Helvetica字体,我还为几个字符获得了很好的边界框值:Cocoa CATextLayer中不需要的填充,cocoa,core-animation,core-text,Cocoa,Core Animation,Core Text,我在CATextLayer中绘制角色时遇到了一个问题,使得该层正好是角色的大小 我使用下面的代码来获得与字符串中的字符对应的glyph的大小。目前,我忽略了历时性,因此我假设字形和字符之间存在一对一的相关性 对于大小为128pt的Helvetica字体,我还为几个字符获得了很好的边界框值: Character | x | y | width | height | B | 9.4 | 0.0 | 70.8 | 91.8 | y | 1.3 |
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;
}
这是我从上述代码中得到的结果。在我看来,大小是正确的,但是角色周围有一些填充
现在我的问题
用
CTFontCreatePathForGlyph
从一个glyph创建一个CGPath
,然后用CGPathGetBoundingBox
获取它的边界框怎么样
另一种方法是以某种方式创建
CTRun
,并使用CTRunGetImageBounds
函数,该函数还返回一个“紧密”边界框,但这可能需要比上述方法更多的代码行,并且您需要有一个图形上下文。如何使用CTFontCreatePathForGlyph
从字形创建CGPath
,然后使用CGPathGetBoundingBox
获取其边界框
另一种方法是以某种方式创建
CTRun
,并使用CTRunGetImageBounds
函数,该函数还返回一个“紧密”边界框,但这可能需要比上述方法更多的代码行,并且您需要一个图形上下文。我认为这与字母周围的内置空间有关。它们的边界框通常包含一定数量的空间,如果您在一行中组装glyph,这些空间将用作一般间距。然后使用紧排表对这些参数进行优化
是的,提取实际的bezier路径是获得紧边界框的一种非常好的方法。虽然我没有使用CATextLayers的经验,但我已经做了很多年了。我想这与字母周围的内置空间有关。它们的边界框通常包含一定数量的空间,如果您在一行中组装glyph,这些空间将用作一般间距。然后使用紧排表对这些参数进行优化
是的,提取实际的bezier路径是获得紧边界框的一种非常好的方法。虽然我没有使用CATextLayers的经验,但我已经做了很多年了。这是一个有趣的方法。这将解决原点坐标小于零的边界框问题。因此,我们只需在grahics上下文中绘制路径,并绕过设置字符串属性的CATextLayer机制?我没有真正考虑绘图部分,但是是的,除非您需要CATextLayer的其他功能,你当然可以这样做。这还有一个问题:我想根据多个文本层的基线对齐多个文本层,因此我想得到字符的总体大小,包括填充。嗯,您最好还是自己绘制文本,因为没有文档记录
CATextLayer
如何精确计算其布局。我不知道如何从CATextLayer
中获取基线,但如果使用核心文本绘制,则很容易做到。这是一种有趣的方法。这将解决原点坐标小于零的边界框问题。因此,我们只需在grahics上下文中绘制路径,并绕过设置字符串属性的CATextLayer机制?我没有真正考虑绘图部分,但是是的,除非您需要CATextLayer的其他功能,你当然可以这样做。这还有一个问题:我想根据多个文本层的基线对齐多个文本层,因此我想得到字符的总体大小,包括填充。嗯,您最好还是自己绘制文本,因为没有文档记录CATextLayer
如何精确计算其布局。我不知道如何从CATextLayer
中获取基线,但如果使用核心文本绘制,则很容易做到。好的,因此采用贝塞尔路径将给出不带填充的图示符的大小。但要显示它,我必须直接使用CoreGraphics。我将查找CoreText API,以确定是否可以将空格包括在Glyph.OK的度量中,因此采用bezier路径将给出不带填充的Glyph的大小。但要显示它,我必须直接使用CoreGraphics。我将查找CoreTextAPI,以了解是否可以将空格包含在字形的度量中。