NSString 大小不考虑希腊呼吸标记

NSString sizing does not account for Greek breathing marks

我有一个显示希腊文字的应用程序。我使用 Cardo 字体以获得良好的显示效果。在开发 AppleWatch 扩展和应用程序时,有人向我指出一些特殊字符被切断了。这是一些示例文本的外观(来自 iPhone 模拟器的屏幕截图):

以下是 Watch 模拟器上的相同文本:

请注意,第一个单词的第二个字符上的花式重音字符(具体来说,带有抑扬音符的呼吸标记)被截掉了。我尝试使用一些 NSString 测量代码在 phone 上设置标签的框架,如下所示:

UILabel *label = [[UILabel alloc]init];
label.font = [UIFont fontWithName:@"Cardo" size:16];
[self.view addSubview:label];
label.text = @"οὗτος ἦλθεν εἰς μαρτυρίαν ἵνα μαρτυρήσῃ περὶ τοῦ φωτός, ἵνα πάντες πιστεύσωσιν δι᾽ αὐτοῦ.";
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init];
style.lineBreakMode = NSLineBreakByWordWrapping;

CGRect rect = [label.text boundingRectWithSize:self.view.bounds.size
  options:NSStringDrawingUsesLineFragmentOrigin
  attributes:@{NSFontAttributeName: label.font,
     NSParagraphStyleAttributeName: style} context:nil];
label.frame = CGRectMake(5, 100, ceilf(rect.size.width), ceilf(rect.size.height));
label.layer.borderWidth = 1; //for clarity
label.layer.borderColor = [UIColor blackColor].CGColor;

结果如下所示(为清楚起见画了边框):

有趣的是,如果我使用系统字体而不是 Cardo,额外的符号会正确显示:

那么,我的问题:是什么原因导致 NSString 尺码裁掉多余的标记?是否有一些选项可以传递给调整大小的方法来纠正这个问题?或者更好的是,我可以在 Watch 应用程序的 WKInterfaceLabel 上设置一些选项以使其正确呈现吗?

我怀疑问题出在字体本身,上行字母设置得太紧,无法正常显示。

我会首先尝试通过创建 UILabel 的子类并覆盖 drawTextInRect 来设置 UILabel 的文本插入:

- (void)drawTextInRect:(CGRect)rect {
UIEdgeInsets insets = {5, 0, 0, 0};
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}

如果您尝试增加文本插入以适应字体但没有奏效,请查看 Custom installed font not displayed correctly in UILabel

我不知道这是否会解决它,但这会给你更多的东西来研究。我 运行 遇到了使用 "Lower Case" 数字的字体问题,这是表格数字的排版样式。我能够使用强制所有数字为大写的 UIFontDescription 创建字体的变体。在你的例子中,字体的上升部分超过了字体的 capHeight 的顶部。使用字体描述符创建字体有很多选项,其中一个可能会有所帮助。这是我创建大写数字字体的方法。

_font = [UIFont fontWithName:_fontName size:size];

NSArray* featureSettings = @[
            @{
                 UIFontFeatureTypeIdentifierKey: @(kNumberCaseType),
                 UIFontFeatureSelectorIdentifierKey: @(kUpperCaseNumbersSelector)
            }];


UIFontDescriptor* originalDescriptor = [_font fontDescriptor];
UIFontDescriptor* newDescriptor = [originalDescriptor fontDescriptorByAddingAttributes: @{UIFontDescriptorFeatureSettingsAttribute: featureSettings }];
_font = [UIFont fontWithDescriptor: newDescriptor size: size];

具体查看kVerticalPositionType。

我实际上 运行 在我的 iOS 应用程序中遇到了一个案例,其中字体上升器从基线向上超过了 capHeight 并且我的属性字符串被切断了。由于我使用的是石英绘图代码,所以我只是使用字体的 lineHeight 与其上升器的差异并填充顶部。不幸的是,这不是 Apple Watch 上的一个选项。