Get font face from ttf file
Asked Answered
M

3

2

In my iOS app I use custom fonts, dynamically loaded from files.

To use them in code, I need to know loaded fonts' families. So, is there any way to do it?

UPDATE:

I can't somehow hardcode font families, cause my app loads it from server. Of course, there is a way to pass font families in server response, but for now I'm looking for a better version that doesn't influence the server (doesn't need to change it).

Mediatize answered 12/2, 2013 at 3:18 Comment(0)
M
1

Font loading I did...

NSData *fontData = [NSData dataWithContentsOfFile:filePath];
if (fontData) {
    // create font from loaded data and get it's postscript name
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithCFData((CFDataRef)fontData);
    CGFontRef loadedFont = CGFontCreateWithDataProvider(fontDataProvider);
    NSString *postScriptName = (NSString *)CGFontCopyPostScriptName(loadedFont);

    // if the font with same postscript name wasn't already registered - do it
    if (postScriptName && ![UIFont fontWithName:postScriptName size:10]) {
        NSError *error;
        if (!CTFontManagerRegisterGraphicsFont(loadedFont, (CFErrorRef *)&error)) {
            NSLog(@"Can't load font: %@", error);
        }
    }

    CGFontRelease(loadedFont);
    CGDataProviderRelease(fontDataProvider);
}
Mediatize answered 8/7, 2013 at 5:34 Comment(0)
B
0

In the docs see the section called Getting the Available Font Names. You can list all family names, and individual font names of the family you want. I usually just pause the debugger and call the functions myself from the command line. It is the safest way to get the name that iOS will use. Or are you talking about downloading fonts and loading them? That will require more than just knowing their names.

EDIT Ok, then you are downloading fonts. In that case, you will have to drop into the world of Core Text. See this reference to get started (pay attention to the functions called "register font"). If you successfully register it, then it will show up using the above methods.

Bishop answered 12/2, 2013 at 3:23 Comment(7)
Thanks for your response, but I can't use this approach. See the reason in my updated question.Mediatize
Alright then, prepare for some trouble, because you need to drop down into CoreText. See my update.Bishop
Thanks, but I've read CoreText reference before asking my question. And all methods there need font-family. Maybe, I can pass any app-unique string, but there comes another problem: if font has same Postscript with one of already registered - it wouldn't be registered itself and I don't know how to get "same" font in this situation.Mediatize
In the case of same fonts, unregister the existing one, and then register yours. You don't need the font-family name to register, you only need a URL CTFontManagerRegisterFontsForURL. If you need the font family for that font, you can look into CTFontRef.Bishop
I get the first font file (with some name) and should use it to render some text. Then I get the second font file (with possibly different name, but the same font) and should use it to render some more text. So I can't unregister fist one, but should somehow use them both or detect that the first and the second are the same...Mediatize
How can you expect to use them both if they are the same exact font name? How will the system know which one to pick? How will anyone know which one to pick? Anyway there is another type called CGFontRef which will allow you to initialize a font from a file, and look at its properties without registering it. So when you download, first try to register it, and look at the error if it fails (it will tell you if another font with the same name is already registered). After that you can check all of your currently downloaded fonts to see if any of the post script names match.Bishop
If none of your downloaded fonts match then you can assume you are trying to use a font that is already installed on the system (pointless). Basically, just don't allow the user to use two fonts in this way. Fail immediately on download and popup an alert to explain why.Bishop
S
0

I got this code from somewhere on stack overflow. Hope it helps. It lists all the loaded font names...

NSArray *familyNames = [[NSArray alloc] initWithArray:[UIFont familyNames]];

NSArray *fontNames;
NSInteger indFamily, indFont;
for (indFamily=0; indFamily<[familyNames count]; ++indFamily) {
   NSLog(@"Family name: %@", [familyNames objectAtIndex:indFamily]);
   fontNames = [[NSArray alloc] initWithArray:
   [UIFont fontNamesForFamilyName:
   [familyNames objectAtIndex:indFamily]]];
   for (indFont=0; indFont<[fontNames count]; ++indFont) {
      NSLog(@"    Font name: %@", [fontNames objectAtIndex:indFont]);
   }
}
Superb answered 12/2, 2013 at 4:45 Comment(1)
Yes, I can get font names for me (developer). But fonts are dynamically loaded from server, so I don't know all of them (and they can be added to the server).Mediatize

© 2022 - 2024 — McMap. All rights reserved.