Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CTFontManagerRegisterGraphicsFont does not register the family name

For reasons related to licensing, I have to decrypt a font file and load it into memory then then register it instead of reading directly from a URL. For this I have to use CTFontManagerRegisterGraphicsFont.

The problematic part comes when I try to use [NSFont fontWithName:@"Open Sans" size:21.0] where it will only accept the font's PostScript name (i.e. ("OpenSans or OpenSans-Bold for the bold weight) and won't work the family name "Open Sans".

If a font is registered using ATSApplicationFontsPathin the info.plist file or using CTFontManagerRegisterFontsForURLs then I am able to use the font's family name. But I can't do it this way.

("Open Sans" is used here as an example)

Here's the relevant code I'm using to register the font.

NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"OpenSans-Regular" ofType:@"ttf" inDirectory:@"Fonts"];
NSData *fontData = [NSData dataWithContentsOfFile:fontPath];

CGDataProviderRef fontProviderRef = CGDataProviderCreateWithCFData((CFDataRef)fontData);
CGFontRef fontRef = CGFontCreateWithDataProvider(fontProviderRef);
CFErrorRef error;

if (! CTFontManagerRegisterGraphicsFont(fontRef, &error)) {

    CFStringRef errorDescription = CFErrorCopyDescription(error);
    NSLog(@"Failed to load font: %@", errorDescription);
    CFRelease(errorDescription);
}

CFRelease(fontRef);
CFRelease(fontProviderRef);

Is there a way to make the font family name available to NSFont with CTFontManagerRegisterGraphicsFont?

(Using Xcode 5 and targeting Mac OS X >= 10.8)

like image 287
Salaryman Avatar asked Feb 14 '14 19:02

Salaryman


1 Answers

update:

Ok, to verify that the family name comes from the font file itself: I tried this with a font I have... GillSansMTStd-Light. I changed the family name in the font file to "Gill Sans Std Mt Light", and subsequently I could use [ NSFont fontWithName:@"Gill Sans MT Std Light" size:10.0 ].

fontforge font info panel:

enter image description here

before:

enter image description here

after:

enter image description here


I looked through all the combinations of CT/NS font and font manager APIs I could think of. Seems there is no API to associate a family name with a font--I think this data comes from the font file itself.

I guess there needs to be a (Mac) font family and font subfamily entry in the font name table. (cf. https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html)

I have used FontForge to edit font files in the past--maybe that can help you? Seems you can install it via homebrew.

Finally, I think there's an easier way to add a font to the CTFontManager. I changed your code to:

// register the font:
NSURL * url = [[ NSBundle mainBundle ] URLForResource:@"OpenSans-Regular" withExtension:@"ttf" ] ;
assert( url ) ;

CFErrorRef error = 0 ;
bool ok = CTFontManagerRegisterFontsForURL( (__bridge CFURLRef)url, kCTFontManagerScopeProcess, &error ) ;
assert( ok && !error ) ;

// make sure it's registered (using PS name): 
CTFontRef f = CTFontCreateWithName( CFSTR( "OpenSans-Regular" ), 10.0, NULL ) ;
assert( f ) ;
like image 65
nielsbot Avatar answered Sep 18 '22 08:09

nielsbot