How to convert CGFontRef to UIFont?

随声附和 提交于 2019-11-26 16:26:39

问题


I want to use a custom font for a UILabel. The custom font is loaded by from a file:

NSString *fontPath = ... ; // a TTF file in iPhone Documents folder
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);
CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider); 

How can I convert the CGFontRef to a UIFont to be used in [UILabel setFont:]?


回答1:


Conrad's answer is close but doesn't quite work. You need to provide UIFont with the PostScript name, rather than the full name.

NSString *fontName = (NSString *)CGFontCopyPostScriptName(fontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize]



回答2:


You can't convert CGFontRef to UIFont directly but you can register CGFontRef using CTFontManagerRegisterGraphicsFont and then create corresponding UIFont.

NSString* fpath = [documentsDirectory stringByAppendingPathComponent:@"custom_font_file_name.ttf"];
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fpath UTF8String]);
CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
NSString *fontName = (__bridge NSString *)CGFontCopyFullName(customFont);
CFErrorRef error;
CTFontManagerRegisterGraphicsFont(customFont, &error);
CGFontRelease(customFont);
UIFont* uifont = [UIFont fontWithName:fontName size:12];



回答3:


They are, in principle, not directly convertible. One simple reason is that UIFont encapsulates font size, whereas CGFont is size-independent (with size being a property of the graphics context; see CGContextSetFontSize()).

Assuming that you have otherwise determined what font size you want, you should be able to something like:

NSString *fontName = (NSString *)CGFontCopyFullName(someCGFontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize];
[fontName release];

I haven't actually tested this, but it should work (maybe with some minor additions). I believe that there is a correspondence between names for CGFont and UIFont - but if there isn't, this obviously won't work.




回答4:


CTFontRef and UIFont are toll-free bridged, so you can turn your CGFont into a CTFont and then turn that into a UIFont:

CTFontRef ctFont = CTFontCreateWithGraphicsFont(cgFont, pointSize, NULL, NULL);
UIFont *uiFont = CFBridgingRelease(ctFont);



回答5:


You can convert your CGFont to CTFont, but unfortunately neither of those will get you a UIFont. Here are the ways to get a UIFont: ask for a system font, or ask for a font by its PostScript name. Therefore, for custom supplied fonts in a UILabel, I suggest you use the latter.

If you know the font file your app will use ahead of time you can add it to your bundle and load it with UIFont, +fontWithName:size: as UIFont searches your bundle for a font file with that PostScript name.

For example, the TrueType font file "VeraMono.ttf" has PostScript name "Bitstream Vera Sans Mono", so it's loaded into a UILabel like:

label.font = [UIFont fontWithName:@"Bitstream Vera Sans Mono" size:12];

To get PostScript names non-dynamically, use a font tool, or, in the case above the PostScript name happens to be equal to the "Full Name" display by Finder > Get Info.

However, for cases where you won't necessarily know the font's PostScript name ahead of time (such as supporting user-defined fonts), perhaps you can load the filename into NSData and "grep" for its PostScript name...

Good luck,




回答6:


Updated for Swift 4 to get PostScript name (where font is the CGFont):

let fontName = font?.postScriptName as String?
textLabel.font = UIFont(name: fontName!, size: 17)


来源:https://stackoverflow.com/questions/9205709/how-to-convert-cgfontref-to-uifont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!