objective-c - 为什么此文本会改变 Yosemite 中的字符?

标签 objective-c macos cocoa fonts

我正在尝试更新优胜美地的应用程序,我遇到的一个奇怪的问题是自定义控件上的文本标签正在更改字符 - 不是扭曲,而是从“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(CTLineCTRun)获取字形索引,但它不提供字体。据推测,Core Text 使用的是默认字体。后来,它使用这些字形索引,但传递的是所需的字体,而不是 Core Text 使用的字体。因此,字形索引并不意味着同一件事。

我认为解决方案是在该方法中使用字体属性构造属性字符串:

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:@{ NSFontAttributeName: font }];

(通常,您必须小心使用 Core Text 能够理解的属性,但我相信 NSFontAttributeName 映射到 kCTFontAttributeNameNSFont 免费桥接到 CTFont。)

关于objective-c - 为什么此文本会改变 Yosemite 中的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26446651/

相关文章:

macos - NSTextField 颜色光标

mysql - 新鲜的 MySQL Workbench 安装在 Mac OSX Lion 上没有响应

ios - dispatch_sync 总是在主线程上调度一个 block

ios - Facebook 登录后重定向到新的 ViewController

mysql - 为什么在 MAC OSX 上编译简单的 mysql c 应用程序时不断收到 undefined symbol ?

iphone - drawRect 的 rect != self.frame 时的条件

facebook - 将网页 URL 分享到 Facebook

objective-c - Snow Leopard 中的文件大小

ios - 加速 : Finding pointer address for vDSP_maxviD

ios - 从 Presentmodelview 堆栈中移除 UIViewcontroller