Получить шрифт из файла ttf

В моем приложении для iOS я использую пользовательские шрифты, динамически загружаемые из файлов.

Чтобы использовать их в коде, мне нужно знать семейства загружаемых шрифтов. Итак, есть ли способ сделать это?

ОБНОВЛЕНИЕ:

Я не могу каким-то образом жестко закодировать семейства шрифтов, потому что мое приложение загружает их с сервера. Конечно, есть способ передавать семейства шрифтов в ответе сервера, но пока я ищу лучший вариант, который не влияет на сервер (не нужно его менять).


person kpower    schedule 12.02.2013    source источник


Ответы (3)


Загрузка шрифта я сделал...

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);
}
person kpower    schedule 08.07.2013

В документах см. раздел под названием Получение доступных имен шрифтов. Вы можете перечислить все имена семейств и отдельные имена шрифтов семейства, которое вы хотите. Обычно я просто приостанавливаю работу отладчика и сам вызываю функции из командной строки. Это самый безопасный способ получить имя, которое будет использовать iOS. Или вы говорите о загрузке шрифтов и их загрузке? Для этого потребуется больше, чем просто знать их имена.

EDIT Итак, вы загружаете шрифты. В этом случае вам придется погрузиться в мир основного текста. См. эту ссылку, чтобы начать работу. (обратите внимание на функции под названием «зарегистрировать шрифт»). Если вы успешно зарегистрируете его, он появится с использованием вышеуказанных методов.

person borrrden    schedule 12.02.2013
comment
Спасибо за ваш ответ, но я не могу использовать этот подход. Смотрите причину в моем обновленном вопросе. - person kpower; 12.02.2013
comment
Хорошо, тогда приготовьтесь к неприятностям, потому что вам нужно спуститься в CoreText. Смотрите мое обновление. - person borrrden; 12.02.2013
comment
Спасибо, но я прочитал справочник CoreText, прежде чем задать свой вопрос. И все методы там нуждаются в font-family. Возможно, я могу передать любую строку, уникальную для приложения, но возникает другая проблема: если шрифт имеет тот же Postscript, что и один из уже зарегистрированных - он не будет зарегистрирован сам, и я не знаю, как получить такой же шрифт в этой ситуации. - person kpower; 12.02.2013
comment
В случае одинаковых шрифтов отмените регистрацию существующего, а затем зарегистрируйте свой. Вам не нужно имя семейства шрифтов для регистрации, вам нужен только URL-адрес CTFontManagerRegisterFontsForURL. Если вам нужно семейство шрифтов для этого шрифта, вы можете посмотреть CTFontRef. - person borrrden; 13.02.2013
comment
Я получаю первый файл шрифта (с каким-то именем) и должен использовать его для рендеринга текста. Затем я получаю второй файл шрифта (возможно, с другим именем, но с тем же шрифтом) и должен использовать его для отображения еще одного текста. Поэтому я не могу отменить регистрацию первого, но должен каким-то образом использовать их оба или обнаружить, что первое и второе одинаковы... - person kpower; 13.02.2013
comment
Как вы можете ожидать использовать их оба, если они имеют одно и то же точное имя шрифта? Как система узнает, какой из них выбрать? Как кто-нибудь узнает, какой из них выбрать? В любом случае есть еще один тип, называемый CGFontRef, который позволит вам инициализировать шрифт из файла и просматривать его свойства без его регистрации. Поэтому, когда будете скачивать, сначала попробуйте его зарегистрировать, а если не получится, посмотрите на ошибку (он сообщит, зарегистрирован ли уже другой шрифт с таким же именем). После этого вы можете проверить все ваши загруженные в данный момент шрифты, чтобы увидеть, совпадают ли какие-либо имена постскриптумов. - person borrrden; 13.02.2013
comment
Если ни один из загруженных вами шрифтов не подходит, вы можете предположить, что пытаетесь использовать шрифт, который уже установлен в системе (бессмысленно). По сути, просто не позволяйте пользователю использовать два шрифта таким образом. Сбой сразу при загрузке и всплывающее предупреждение с объяснением причины. - person borrrden; 13.02.2013

Я получил этот код откуда-то при переполнении стека. Надеюсь, поможет. В нем перечислены все загруженные имена шрифтов...

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]);
   }
}
person samuel Schweighart    schedule 12.02.2013
comment
Да, я могу получить названия шрифтов для себя (разработчика). Но шрифты загружаются с сервера динамически, поэтому я их всех не знаю (и их можно добавить на сервер). - person kpower; 12.02.2013