Общие операции шрифта
В этой главе описываются некоторые общие погрузочно-разгрузочные работы шрифта и показывает, как кодировать их использующий Базовый текст. Эти операции являются тем же на iOS и OS X. Следующие операции с листингами кода включены в эту главу:
Создание дескрипторов шрифта
Функция в качестве примера в Перечислении 3-1 создает дескриптор шрифта из значений параметров, указывающих имя шрифта PostScript и размер точки.
Перечисление 3-1 , Создающее дескриптор шрифта из имени и размера точки
CTFontDescriptorRef CreateFontDescriptorFromName(CFStringRef postScriptName, |
CGFloat size) |
{ |
return CTFontDescriptorCreateWithNameAndSize(postScriptName, size); |
} |
Функция в качестве примера в Перечислении 3-2 создает дескриптор шрифта из имени семейства шрифтов и черт шрифта.
Перечисление 3-2 , Создающее дескриптор шрифта из семьи и черт
NSString* familyName = @"Papyrus"; |
CTFontSymbolicTraits symbolicTraits = kCTFontTraitCondensed; |
CGFloat size = 24.0; |
NSMutableDictionary* attributes = [NSMutableDictionary dictionary]; |
[attributes setObject:familyName forKey:(id)kCTFontFamilyNameAttribute]; |
// The attributes dictionary contains another dictionary, the traits dictionary, |
// which in this example specifies only the symbolic traits. |
NSMutableDictionary* traits = [NSMutableDictionary dictionary]; |
[traits setObject:[NSNumber numberWithUnsignedInt:symbolicTraits] |
forKey:(id)kCTFontSymbolicTrait]; |
[attributes setObject:traits forKey:(id)kCTFontTraitsAttribute]; |
[attributes setObject:[NSNumber numberWithFloat:size] |
forKey:(id)kCTFontSizeAttribute]; |
CTFontDescriptorRef descriptor = |
CTFontDescriptorCreateWithAttributes((CFDictionaryRef)attributes); |
CFRelease(descriptor); |
Создание шрифта от дескриптора шрифта
Перечисление 3-3 показывает, как создать дескриптор шрифта и использовать его для создания шрифта. Когда Вы вызываете CTFontCreateWithFontDescriptor
, Вы обычно передаете NULL
для параметра матрицы для указания значения по умолчанию (идентификационные данные) матрица. Размер и матрица (второй и третий) параметры CTFontCreateWithFontDescriptor
переопределите любого указанного в дескрипторе шрифта, если они не являются неуказанными (0.0
для размера и NULL
для матрицы).
Перечисление 3-3 , Создающее шрифт из дескриптора шрифта
NSDictionary *fontAttributes = |
[NSDictionary dictionaryWithObjectsAndKeys: |
@"Courier", (NSString *)kCTFontFamilyNameAttribute, |
@"Bold", (NSString *)kCTFontStyleNameAttribute, |
[NSNumber numberWithFloat:16.0], |
(NSString *)kCTFontSizeAttribute, |
nil]; |
// Create a descriptor. |
CTFontDescriptorRef descriptor = |
CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes); |
// Create a font using the descriptor. |
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL); |
CFRelease(descriptor); |
Создание связанных шрифтов
Часто полезно преобразовать существующий шрифт в связанный или похожий шрифт. Функция в качестве примера в Перечислении 3-4 показывает, как сделать шрифт полужирным, или неполужирный на основе значения булева параметра передал с вызовом функции. Если у семьи текущего шрифта нет необходимого стиля, функциональных возвратов NULL
.
Перечисление 3-4 , Изменяющее черты шрифта
CTFontRef CreateBoldFont(CTFontRef font, Boolean makeBold) |
{ |
CTFontSymbolicTraits desiredTrait = 0; |
CTFontSymbolicTraits traitMask; |
// If requesting that the font be bold, set the desired trait |
// to be bold. |
if (makeBold) desiredTrait = kCTFontBoldTrait; |
// Mask off the bold trait to indicate that it is the only trait |
// to be modified. As CTFontSymbolicTraits is a bit field, |
// could change multiple traits if desired. |
traitMask = kCTFontBoldTrait; |
// Create a copy of the original font with the masked trait set to the |
// desired value. If the font family does not have the appropriate style, |
// returns NULL. |
return CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, desiredTrait, traitMask); |
} |
Функция в качестве примера в Перечислении 3-8 преобразовывает данный шрифт в похожий шрифт в другом семействе шрифтов, сохраняя черты, если это возможно. Это может возвратиться NULL
. Передача в 0.0
для параметра размера и NULL
поскольку параметр матрицы сохраняет размер от исходного шрифта.
Перечисление 3-5 , Преобразовывающее шрифт в другую семью
CTFontRef CreateFontConvertedToFamily(CTFontRef font, CFStringRef family) |
{ |
// Create a copy of the original font with the new family. This call |
// attempts to preserve traits, and may return NULL if that is not possible. |
// Pass in 0.0 and NULL for size and matrix to preserve the values from |
// the original font. |
return CTFontCreateCopyWithFamily(font, 0.0, NULL, family); |
} |
Сериализация шрифта
Функция в качестве примера в Перечислении 3-6 показывает, как создать данные XML для сериализации шрифта, который может быть встроен в документ. Также и предпочтительно, NSArchiver
мог использоваться. Это - всего один способ выполнить эту задачу, но это сохраняет все данные от шрифта, должен был воссоздать точный шрифт в более позднее время.
Перечисление 3-6 , Сериализирующее шрифт
CFDataRef CreateFlattenedFontData(CTFontRef font) |
{ |
CFDataRef result = NULL; |
CTFontDescriptorRef descriptor; |
CFDictionaryRef attributes; |
// Get the font descriptor for the font. |
descriptor = CTFontCopyFontDescriptor(font); |
if (descriptor != NULL) { |
// Get the font attributes from the descriptor. This should be enough |
// information to recreate the descriptor and the font later. |
attributes = CTFontDescriptorCopyAttributes(descriptor); |
if (attributes != NULL) { |
// If attributes are a valid property list, directly flatten |
// the property list. Otherwise we may need to analyze the attributes |
// and remove or manually convert them to serializable forms. |
// This is left as an exercise for the reader. |
if (CFPropertyListIsValid(attributes, kCFPropertyListXMLFormat_v1_0)) { |
result = CFPropertyListCreateXMLData(kCFAllocatorDefault, attributes); |
} |
} |
} |
return result; |
} |
Создание шрифта от сериализированных данных
Функция в качестве примера в Перечислении 3-7 показывает, как создать ссылку шрифта из сглаженных данных XML. Это показывает, как не сгладить атрибуты шрифта и создать шрифт с теми атрибутами.
Перечисление 3-7 , Создающее шрифт из сериализированных данных
CTFontRef CreateFontFromFlattenedFontData(CFDataRef iData) |
{ |
CTFontRef font = NULL; |
CFDictionaryRef attributes; |
CTFontDescriptorRef descriptor; |
// Create our font attributes from the property list. |
// For simplicity, this example creates an immutable object. |
// If you needed to massage or convert certain attributes |
// from their serializable form to the Core Text usable form, |
// do it here. |
attributes = |
(CFDictionaryRef)CFPropertyListCreateFromXMLData( |
kCFAllocatorDefault, |
iData, kCFPropertyListImmutable, NULL); |
if (attributes != NULL) { |
// Create the font descriptor from the attributes. |
descriptor = CTFontDescriptorCreateWithAttributes(attributes); |
if (descriptor != NULL) { |
// Create the font from the font descriptor. This sample uses |
// 0.0 and NULL for the size and matrix parameters. This |
// causes the font to be created with the size and/or matrix |
// that exist in the descriptor, if present. Otherwise default |
// values are used. |
font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL); |
} |
} |
return font; |
} |
Изменение кернинга
Лигатуры и кернинг включены по умолчанию. Для отключения установите kCTKernAttributeName
атрибут к 0
. Перечисление 3-8 устанавливает размер керна в большое количество для первых нескольких нарисованных символов.
Кернинг Установки перечисления 3-8
// Set the color of the first 13 characters to red |
// using a previously defined red CGColor object. |
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 13), |
kCTForegroundColorAttributeName, red); |
// Set kerning between the first 18 chars to be 20 |
CGFloat otherNum = 20; |
CFNumberRef otherCFNum = CFNumberCreate(NULL, kCFNumberCGFloatType, &otherNum); |
CFAttributedStringSetAttribute(attrString, CFRangeMake(0,18), |
kCTKernAttributeName, otherCFNum); |
Получение глифов для символов
Перечисление 3-9 показывает, как получить глифы для символов в строке с единственным шрифтом. Большую часть времени необходимо просто использовать объект CTLine получить эту информацию, потому что один шрифт может не закодировать всю строку. Кроме того, простое отображение символа к глифу не получит корректное появление для сложных сценариев. При попытке вывести на экран определенные символы Unicode для шрифта, это простое отображение глифа может быть надлежащим.
Перечисление 3-9 , Получающее глифы для символов
void GetGlyphsForCharacters(CTFontRef font, CFStringRef string) |
{ |
// Get the string length. |
CFIndex count = CFStringGetLength(string); |
// Allocate our buffers for characters and glyphs. |
UniChar *characters = (UniChar *)malloc(sizeof(UniChar) * count); |
CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * count); |
// Get the characters from the string. |
CFStringGetCharacters(string, CFRangeMake(0, count), characters); |
// Get the glyphs for the characters. |
CTFontGetGlyphsForCharacters(font, characters, glyphs, count); |
// Do something with the glyphs here. Characters not mapped by this font will be zero. |
// ... |
// Free the buffers |
free(characters); |
free(glyphs); |
} |