matchingFontDescriptorsWithMandatoryKeys如何匹配字体描述符?

时间:2014-01-27 13:45:13

标签: cocoa fonts

我正在使用-[NSFontDescriptor matchingFontDescriptorsWithMandatoryKeys:]方法来查找系统中是否已安装字体,但结果却非常奇怪。

这是一个小程序,用于测试给定字体是否与已安装的字体匹配:

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>

void logFontDescriptor(NSString *message, NSFontDescriptor *fontDescriptor, NSArray *attributeKeys)
{
    printf("%s %s\n", [message UTF8String], [fontDescriptor.postscriptName UTF8String]);
    for (NSString *attributeKey in attributeKeys)
    {
        printf("    %30s -> %s\n", [[attributeKey description] UTF8String], [[[fontDescriptor objectForKey:attributeKey] description] UTF8String]);
    }
    printf("\n");
}

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        if (argc != 2)
            return EXIT_FAILURE;

        NSArray *mandatoryKeys = @[ NSFontNameAttribute, NSFontFamilyAttribute, NSFontFaceAttribute ];

        NSURL *fontURL = [NSURL fileURLWithPath:@(argv[1])];
        NSArray *fontDescriptors = CFBridgingRelease(CTFontManagerCreateFontDescriptorsFromURL((__bridge CFURLRef)fontURL));
        for (NSFontDescriptor *fontDescriptor in fontDescriptors)
        {
            logFontDescriptor(@"***", fontDescriptor, mandatoryKeys);

            NSArray *matchingFontDescriptors = [fontDescriptor matchingFontDescriptorsWithMandatoryKeys:[NSSet setWithArray:mandatoryKeys]];
            for (NSFontDescriptor *matchingFontDescriptor in matchingFontDescriptors)
            {
                logFontDescriptor(@"  MATCHING", matchingFontDescriptor, mandatoryKeys);
            }
        }
    }
    return EXIT_SUCCESS;
}

要重现这种奇怪的行为,请下载Ubuntu Font Family并仅将Ubuntu-B.ttf Ubuntu Bold )文件复制到~/Library/Fonts目录中。然后使用Ubuntu-R.ttf Ubuntu Regular )运行此测试程序:

./font_descriptor_matching ~/Downloads/ubuntu-font-family-0.80/Ubuntu-R.ttf

现在,您的系统上安装了 Ubuntu Bold 字体,并且您正在询问哪些字体描述符匹配 Ubuntu Regular ,这是结果(OS X 10.9。 1):

*** Ubuntu
               NSFontNameAttribute -> Ubuntu
             NSFontFamilyAttribute -> Ubuntu
               NSFontFaceAttribute -> Regular

  MATCHING Ubuntu-Bold
               NSFontNameAttribute -> Ubuntu-Bold
             NSFontFamilyAttribute -> Ubuntu
               NSFontFaceAttribute -> Bold

询问 Ubuntu Regular 与其字体名称(NSFontNameAttribute),字体系列(NSFontFamilyAttribute)和字体(NSFontFaceAttribute)匹配的字体是否产生< em> Ubuntu Bold 字体匹配。如您所见,唯一匹配的属性是字体系列。字体名称和字体表面都不同,matchingFontDescriptorsWithMandatoryKeys:方法表示这些字体匹配。

我误解了matchingFontDescriptorsWithMandatoryKeys:方法的作用或错误是什么?

其他信息:

  • 如果同时安装了 Ubuntu Bold Ubuntu Regular 字体,则匹配将按预期工作。

  • 所有字体都不存在此问题。

1 个答案:

答案 0 :(得分:1)

为了解决这种奇怪的行为,我使用了这种方法,它通过显式测试所有必需的密钥来抑制不匹配的字体描述符。

static NSArray * ReallyMatchingFontDescriptorsWithMandatoryKeys(NSFontDescriptor *fontDescriptor, NSSet *mandatoryKeys)
{
    NSArray *matchingFontDescriptors = [fontDescriptor matchingFontDescriptorsWithMandatoryKeys:mandatoryKeys];
    NSMutableArray *reallyMatchingFontDescriptors = [matchingFontDescriptors mutableCopy];
    for (NSFontDescriptor *matchingFontDescriptor in matchingFontDescriptors)
    {
        BOOL reallyMatching = YES;
        for (NSString *mandatoryKey in mandatoryKeys)
        {
            if (![[fontDescriptor objectForKey:mandatoryKey] isEqual:[matchingFontDescriptor objectForKey:mandatoryKey]])
                reallyMatching = NO;
        }
        if (!reallyMatching)
            [reallyMatchingFontDescriptors removeObjectIdenticalTo:matchingFontDescriptor];
    }
    return [reallyMatchingFontDescriptors copy];
}