我让用户从安装的字体中选择一种字体,然后在我的 macOS 应用程序的三个不同上下文中使用该字体。
NSFontDescriptor
创建属性字符串,然后将其显示在选项列表中: NSFontDescriptor *fontDescriptor = [NSFontDescriptor fontDescriptorWithName:@"Candara" size:14];
NSDictionary *attributes = @{NSFontAttributeName: [NSFont fontWithDescriptor:fontDescriptor size:14]};
attributedString = [[NSAttributedString alloc] initWithString:@"New Attributed String" attributes:attributes];
NSTextField
中。 NSString *htmlString = @"<!DOCTYPE html>"
"<html>"
"<head>"
"<style>"
"body { font-family: 'Candara', serif; font-size: 14px; }"
"</style>"
"</head>"
"<body>"
"<p>Text with <b>bold</b> or <i>italics</i> maybe.</p>"
"</body>"
"</html>";
NSData *htmlData = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)};
NSError *error;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:htmlData
options:options
documentAttributes:nil
error:&error];
WKWebView
的形式显示。多年来这一切都运作良好。当 macOS 14 出现时,我发现选项 1(用一些使用 Candara 字体的文本初始化
NSAttributedString
)效果很好,选项 3(在 WKWebView
中显示大量使用 Candara 字体的 HTML)效果也很好。 )。但选项2根本不起作用。输出全部是“未定义字符”字形——一个包含问号的框,一个问号对应字符串中的每个字符。
当用户选择 Calibri 或 Candara(这两种字体都是 Microsoft 字体)时,我会看到此行为。我也在 SF Pro 中看到了它,这是一种 Apple 字体。任何其他字体都可以。 (至少从我到目前为止所看到的来看是这样。)
提供后备字体(如上面的“
serif
”所示)不会改变任何内容。渲染不会回退到后备字体;它似乎真的认为它可以使用 Candara,但显然它不能。
随着 macOS 14 的推出,这种行为肯定会出现,并且主要影响那些选择其中一种 Microsoft Office 字体(当然是 Calibri 和 Candara)的用户。但正如我所说,其他字体也可以产生这些结果。
这看起来确实像一个错误,有些字体表现出错误行为,有些却没有。例如,不存在的字体,或者名称中存在拼写错误的字体,仅适用于文件,系统会回退到 Times New Roman 字体。
打印有问题的属性字符串会输出以下内容:
> po attributedString
Text with bold or italics maybe.
{
NSFont = "\"LastResort 14.00 pt. P [] (0x7ff575f14980) fobj=0x7ff575f14980, spc=16.06\"";
NSKern = 0;
NSParagraphStyle = "Alignment Natural, LineSpacing 0, ParagraphSpacing 14, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode WordWrapping, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection LeftToRight, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
NSStrokeColor = "sRGB IEC61966-2.1 colorspace 0 0 0 1";
NSStrokeWidth = 0;
}
对于某些字体(或者可能是某些字符串值),macOS 会回退到 Apple's Last Resort font 字体。对于某些现有字体来说,这显然是不正确的行为,这就是为什么您会看到那些奇怪的字形,因为 macOS 错误地将字体映射到
LastResort
字体,而不是指定的字体,或者至少映射到指定的第二种字体在 CSS 规则中。