我正在尝试更新优胜美地的应用程序,我遇到的一个奇怪的问题是自定义控件上的文本标签正在更改字符 - 不是扭曲,而是从“ON”更改为“KJ”和“关”至“KBB”。这些文档均编码为 UTF-8 文件。如果有人有任何想法,我很乐意听听。
有问题的代码:
AKDrawStringAlignedInFrame(@"OFF", [NSFont boldSystemFontOfSize:0], NSCenterTextAlignment, NSIntegralRect(textRects[0]));
调用:
void AKDrawStringAlignedInFrame(NSString *text, NSFont *font, NSTextAlignment alignment, NSRect frame) {
NSCParameterAssert(font != nil);
NSBezierPath *textPath = [NSBezierPath bezierPathWithString:text inFont:font];
NSRect textPathBounds = NSMakeRect(NSMinX([textPath bounds]), [font descender], NSWidth([textPath bounds]), [font ascender] - [font descender]);
NSAffineTransform *scale = [NSAffineTransform transform];
CGFloat xScale = NSWidth(frame)/NSWidth(textPathBounds);
CGFloat yScale = NSHeight(frame)/NSHeight(textPathBounds);
[scale scaleBy:MIN(xScale, yScale)];
[textPath transformUsingAffineTransform:scale];
textPathBounds.origin = [scale transformPoint:textPathBounds.origin];
textPathBounds.size = [scale transformSize:textPathBounds.size];
NSAffineTransform *originCorrection = [NSAffineTransform transform];
NSPoint centeredOrigin = NSRectFromCGRect(AFRectCenteredSize(NSRectToCGRect(frame), NSSizeToCGSize(textPathBounds.size))).origin;
[originCorrection translateXBy:(centeredOrigin.x - NSMinX(textPathBounds)) yBy:(centeredOrigin.y - NSMinY(textPathBounds))];
[textPath transformUsingAffineTransform:originCorrection];
if (alignment != NSJustifiedTextAlignment && alignment != NSCenterTextAlignment) {
NSAffineTransform *alignmentTransform = [NSAffineTransform transform];
CGFloat deltaX = 0;
if (alignment == NSLeftTextAlignment) deltaX = -(NSMinX([textPath bounds]) - NSMinX(frame));
else if (alignment == NSRightTextAlignment) deltaX = (NSMaxX(frame) - NSMaxX([textPath bounds]));
[alignmentTransform translateXBy:deltaX yBy:0];
[textPath transformUsingAffineTransform:alignmentTransform];
}
[textPath fill];
}
和 +[NSBezierPath bezierPathWithString:inFont:] 只是
+ (NSBezierPath *)bezierPathWithString:(NSString *)text inFont:(NSFont *)font {
NSBezierPath *textPath = [self bezierPath];
[textPath appendBezierPathWithString:text inFont:font];
return textPath;
}
最后,-[appendBezierPathWithString:text] 是:
- (void)appendBezierPathWithString:(NSString *)text inFont:(NSFont *)font {
if ([self isEmpty]) [self moveToPoint:NSZeroPoint];
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text];
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attributedString);
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
CFIndex count = CFArrayGetCount(glyphRuns);
for (CFIndex index = 0; index < count; index++) {
CTRunRef currentRun = (CTRunRef)CFArrayGetValueAtIndex(glyphRuns, index);
CFIndex glyphCount = CTRunGetGlyphCount(currentRun);
CGGlyph glyphs[glyphCount];
CTRunGetGlyphs(currentRun, CTRunGetStringRange(currentRun), glyphs);
NSGlyph bezierPathGlyphs[glyphCount];
for (CFIndex glyphIndex = 0; glyphIndex < glyphCount; glyphIndex++)
bezierPathGlyphs[glyphIndex] = glyphs[glyphIndex];
[self appendBezierPathWithGlyphs:bezierPathGlyphs count:glyphCount inFont:font];
}
CFRelease(line);
}
最佳答案
字形索引特定于字体。 appendBezierPathWithString:inFont:
方法从 Core Text(CTLine
和 CTRun
)获取字形索引,但它不提供字体。据推测,Core Text 使用的是默认字体。后来,它使用这些字形索引,但传递的是所需的字体,而不是 Core Text 使用的字体。因此,字形索引并不意味着同一件事。
我认为解决方案是在该方法中使用字体属性构造属性字符串:
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:@{ NSFontAttributeName: font }];
(通常,您必须小心使用 Core Text 能够理解的属性,但我相信 NSFontAttributeName
映射到 kCTFontAttributeName
和 NSFont
免费桥接到 CTFont
。)
关于objective-c - 为什么此文本会改变 Yosemite 中的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26446651/