I’m using the -[NSFontDescriptor matchingFontDescriptorsWithMandatoryKeys:] method in order to find if a font is already installed in the system but I get very strange results.
Here is a small program to test if a given font matches an installed font:
#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;
}
In order to reproduce the strange behavior, download the Ubuntu Font Family and copy only the Ubuntu-B.ttf
(Ubuntu Bold) file into your ~/Library/Fonts
directory. Then run this test program with Ubuntu-R.ttf
(Ubuntu Regular):
./font_descriptor_matching ~/Downloads/ubuntu-font-family-0.80/Ubuntu-R.ttf
Now, you have the Ubuntu Bold font installed on your system and you are asking what font descriptors are matching Ubuntu Regular and here is the result (OS X 10.9.1):
*** Ubuntu
NSFontNameAttribute -> Ubuntu
NSFontFamilyAttribute -> Ubuntu
NSFontFaceAttribute -> Regular
MATCHING Ubuntu-Bold
NSFontNameAttribute -> Ubuntu-Bold
NSFontFamilyAttribute -> Ubuntu
NSFontFaceAttribute -> Bold
Asking Ubuntu Regular what font matches its font name (NSFontNameAttribute
), font family (NSFontFamilyAttribute
) and font face (NSFontFaceAttribute
) yields that the Ubuntu Bold font matches. As you can see, the only attribute that matches is the font family. Both the font name and font face are different yet the matchingFontDescriptorsWithMandatoryKeys:
method says that these fonts match.
Am I misunderstanding what the matchingFontDescriptorsWithMandatoryKeys:
method does or is it a bug?
Additional Information:
If both the Ubuntu Bold and the Ubuntu Regular fonts are installed then the matching works as expected.
This issue does not exist with all fonts.