четверг, 26 апреля 2012 г.

Загрузка произвольного шрифта из файла средствами CoreText

В  Snow Leopard загрузка произвольного шрифта осуществлялась установкой его в системную папку всех шрифтов. В Lion такое решение deprecated. Тем более с приходом песочницы в 10.8 установка или попытка лезть в систему будет жестко подавлена. Решение в использовании Core Text API.

Последовательность действий File -> CGFontRef -> CTFontRef -> NSFont
Такая схема не работает в SL, разумно использовать старый функционал с заглушками.

Пример загрузки кастомного шрифта из бандла программы.
Для начала, добавим в проект ApplicationServices.framework (уже по умолчанию содержит ссылку на CoreText.framework).

  1. + (CTFontRef) fontFromBundle : (NSString*) fontName 
  2.                   withHeight : (CGFloat) height
  3. {  
  4.     //  
  5.     NSString* fontPath = [[NSBundle mainBundle] pathForResource : fontName 
  6.                                                          ofType : @"ttf" ];   
  7.     if (nil==fontPath)  
  8.         return NULL;  
  9.       
  10.     CGDataProviderRef dataProvider =
  11.     CGDataProviderCreateWithFilename ([fontPath UTF8String]);  
  12.     if (NULL==dataProvider)  
  13.         return NULL;  
  14.       
  15.     //   
  16.     CGFontRef fontRef = CGFontCreateWithDataProvider ( dataProvider );  
  17.     if (NULL == fontRef)  
  18.     {  
  19.         CGDataProviderRelease (dataProvider);   
  20.         return NULL;  
  21.     }      
  22.       
  23.     CTFontRef fontCore = CTFontCreateWithGraphicsFont (fontRef,height,NULL,NULL);  
  24.     CGDataProviderRelease (dataProvider);   
  25.     CGFontRelease (fontRef);  
  26.       
  27.     return fontCore;  
  28. }  

Как использовать в коде.

  1. CTFontRef bundleFont = [CustomFonts fontFromBundle : @"MavenPro-Regular"
  2.                                         withHeight : 25 ];  
  3. NSFont* font = (NSFont*)bundleFont;  
  4. ....  
  5. // use font in application  
  6. ....  
  7. CFRelease(bundleFont);  
  8.    

На заметку.
CoreText можно использовать для рендера сложного текста в UI. В фрэймворке реализована полноценная поддержка Unicode. Поэтому можно использовать прозрачно CTFontRef вместо CGFontRef  при рендере текста в Quartz 2D.