gpt4 book ai didi

objective-c - iOS CoreText : CTFrameSetter is making wider lines than the CGPath allows

转载 作者:行者123 更新时间:2023-12-01 16:58:24 26 4
gpt4 key购买 nike

我正在使用 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;
}

谢谢,
尼古拉斯

最佳答案

我不认为这是一个漂亮的解决方案,但它似乎可以解决您的问题。代码中的以下行负责文本未正确呈现/换行:

[attributedString appendAttributedString:[[[NSAttributedString alloc] initWithString:@" " attributes:attributeDelegate] autorelease]];

CoreText 似乎忽略了添加到 attributedString 中的这些空格。 .
您可以通过简单地添加一个“虚拟”字符来解决此问题,该字符实际上已渲染但与图像重叠,因此不可见。这个字符将被 Coretext 视为一个新的“单词”,应该可以很好地渲染/换行。

例如:
[attributedString appendAttributedString:[[[NSAttributedString alloc] initWithString:@"•" attributes:attributeDelegate] autorelease]];

关于objective-c - iOS CoreText : CTFrameSetter is making wider lines than the CGPath allows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9576585/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com