为什么我在 macOS 14 中从 HTML 创建 NSAttributedString 与使用 initWithString:attributes: 执行相同操作时看到不同的行为?

问题描述 投票:0回答:1

我让用户从安装的字体中选择一种字体,然后在我的 macOS 应用程序的三个不同上下文中使用该字体。

  1. 字体列表本身使用
    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];
  1. 在某些地方,我有一个非常小的 HTML 文档,我将正文字体设置为所选字体,转换为属性字符串,并显示在
    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];
  1. 最后,我在一些地方有更长的 HTML 文档,其字体与正文字体相同,并以
    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)的用户。但正如我所说,其他字体也可以产生这些结果。

html objective-c fonts nsattributedstring macos-sonoma
1个回答
0
投票

这看起来确实像一个错误,有些字体表现出错误行为,有些却没有。例如,不存在的字体,或者名称中存在拼写错误的字体,仅适用于文件,系统会回退到 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 规则中。

© www.soinside.com 2019 - 2024. All rights reserved.