我正在使用CoreText在CGPath
中呈现我的文本,这通常是一个矩形。路径的宽度为230像素。但是当我渲染文本时,CTLineGetTypographicBounds
返回的宽度为292像素而不是最大值230。
在我开始使用CTRunDelegateCallbacks
代表之前,一切正常。我使用它是因为我就地渲染图像。回调只返回消息的正确宽度和高度。我没有看到什么是错的。只有当我向NSAttributedString
添加大量表情时才会发生这种情况。我希望它能正确地将它设置为多行,但事实并非如此。
static void _deallocCallback (void* ref)
{
[(id)ref release];
}
static CGFloat _ascentCallback (void *ref)
{
UIImage* smiley = [(NSDictionary*)ref objectForKey:@"smiley"];
return smiley.size.height; // returns 16
}
static CGFloat _widthCallback (void* ref)
{
UIImage* smiley = [(NSDictionary*)ref objectForKey:@"smiley"];
return smiley.size.width; // returns 16
}
- (void)renderText:(NSString*)text inRect:(CGRect)rect
{
CGMutablePathRef path = createMyPath();
NSAttributedString* attrString = [self _createAttributedString:text];
// Create the frame setter and it's frame
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attrString.length), path, NULL);
// Get the height of the lines
CFArrayRef lines = CTFrameGetLines(frame);
CFIndex lineCount = CFArrayGetCount(lines);
CGFloat ascent, descent, leading;
// Get the origins of each line
CGPoint origins[lineCount];
CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
// Loop through every line
for (CFIndex i = 0; i < lineCount; i++)
{
// Get the typographic bounds of this line
CTLineRef line = (CTLineRef)CFArrayGetValueAtIndex(lines, i);
textWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
// __this returns values wider than rect in path__
}
}
- (NSAttributedString*)_createAttributedString:(NSString*)inString
{
// Create our default font attribute
NSDictionary* fontAttribute = [NSDictionary dictionaryWithObject:(id)_font forKey:(NSString*)kCTFontAttributeName];
// Create the attributed string
NSMutableAttributedString* attributedString = [[NSMutableAttributedString alloc] init];
CTRunDelegateCallbacks callbacks;
callbacks.version = kCTRunDelegateVersion1;
callbacks.getAscent = _ascentCallback;
callbacks.getDescent = NULL;
callbacks.getWidth = _widthCallback;
callbacks.dealloc = _deallocCallback;
UIImage* smiley = getSmiley(@"sad.png");
// Do this multiple times to add a long list of smileys
NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys: smiley, @"smiley", nil];
CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, attributes);
NSDictionary* attributeDelegate = [NSDictionary dictionaryWithObjectsAndKeys:(id)delegate, (NSString *)kCTRunDelegateAttributeName, smiley, @"smiley", nil];
[attributedString appendAttributedString:[[[NSAttributedString alloc] initWithString:@" " attributes:attributeDelegate] autorelease]];
[attributedString appendAttributedString:[[[NSAttributedString alloc] initWithString:@" blablabla " attributes:fontAttribute] autorelease]];
return attributedString;
}
谢谢, 尼古拉斯
答案 0 :(得分:0)
我不认为这是一个很好的解决方案,但似乎可以解决你的问题。代码中的以下行负责正确呈现/包装的文本:
[attributedString appendAttributedString:[[[NSAttributedString alloc] initWithString:@" " attributes:attributeDelegate] autorelease]];
CoreText似乎忽略了添加到attributedString
的这些空格。
您可以通过简单地添加一个“虚拟”字符来解决这个问题,该字符实际上是渲染但由图像重叠并因此不可见。
例如:
[attributedString appendAttributedString:[[[NSAttributedString alloc] initWithString:@"•" attributes:attributeDelegate] autorelease]];