2014-01-27 116 views
3

我使用-[NSFontDescriptor matchingFontDescriptorsWithMandatoryKeys:]方法來查找系統中是否已經安裝了字體,但我得到了非常奇怪的結果。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.ttfUbuntu的大膽)文件進入您的~/Library/Fonts目錄。然後用Ubuntu-R.ttfUbuntu的普通)運行這個測試程序:

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

現在,你有你的系統上安裝Ubuntu的大膽字體和你所要求的字體描述是匹配的Ubuntu的定期這裏是結果(OS X 10.9.1):

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

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

Ubuntu的定期什麼字體的字體名稱(NSFontNameAttribute)匹配,字體法米爾y(NSFontFamilyAttribute)和font face(NSFontFaceAttribute)得出的結果表明Ubuntu Bold字體匹配。如您所見,匹配的唯一屬性是字體系列。字體名稱和字體都是不同的,但matchingFontDescriptorsWithMandatoryKeys:方法表示這些字體匹配。

我誤解matchingFontDescriptorsWithMandatoryKeys:方法做了什麼或者它是一個錯誤?

附加信息:

  • 如果安裝了Ubuntu的大膽的Ubuntu不論是經常字體則匹配按預期工作。

  • 所有字體都不存在此問題。

+0

我打這一點,它看起來就像你發現了一個錯誤,但它是一個奇怪的錯誤,我的意思是,多久你對特質從卸載的字體匹配? 我假設如果Ubuntu-R.ttf也安裝了,它按預期工作?或者那是不正確的? –

+0

我的應用程序安裝字體,所以我想確保不要安裝重複的字體。這就是我爲什麼要匹配卸載的字體的原因。我用更多的信息更新了這個問題,事實上,如果安裝了這兩種字體,則按預期匹配工作。 – 0xced

+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]; 
}