这是一篇旧帖子,但由于没有人发布有效的答案,这里有一个。我CFStringRef
对 ARC 的操作和桥接的知识有点有限,如下所示。随时更正我的代码。
在你的NSLayoutManagerDelegate
,实现shouldGenerateGlyphs
:
-(NSUInteger)layoutManager:(NSLayoutManager *)layoutManager shouldGenerateGlyphs:(const CGGlyph *)glyphs properties:(const NSGlyphProperty *)props characterIndexes:(const NSUInteger *)charIndexes font:(NSFont *)aFont forGlyphRange:(NSRange)glyphRange {
// Get correct indices
NSUInteger location = charIndexes[0];
NSUInteger length = glyphRange.length;
// Create string reference and convert to uppercase
CFStringRef str = (__bridge CFStringRef)[self.textStorage.string substringWithRange:(NSRange){ location, length }];
CFMutableStringRef uppercase = CFStringCreateMutable(NULL, CFStringGetLength(str));
CFStringAppend(uppercase, str);
CFStringUppercase(uppercase, NULL);
// Create glyphs for our new uppercase string
CGGlyph *newGlyphs = GetGlyphsForCharacters((__bridge CTFontRef)(aFont), uppercase);
[self.layoutManager setGlyphs:newGlyphs properties:props characterIndexes:charIndexes font:aFont forGlyphRange:glyphRange];
free(newGlyphs);
return glyphRange.length;
}
CGGlyph* GetGlyphsForCharacters(CTFontRef font, CFStringRef string)
{
// Get the string length.
CFIndex count = CFStringGetLength(string);
// Allocate our buffers for characters and glyphs.
UniChar *characters = (UniChar *)malloc(sizeof(UniChar) * count);
CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * count);
// Get the characters from the string.
CFStringGetCharacters(string, CFRangeMake(0, count), characters);
// Get the glyphs for the characters.
CTFontGetGlyphsForCharacters(font, characters, glyphs, count);
// Free the buffers
free(characters);
return glyphs;
}
我在等宽文本应用程序中成功使用了此代码,在需要更精细脚本的用例中它可能不会那么稳定。