Есть ли в CoreText какое-либо средство для выбора варианта шрифта с маленькими заглавными буквами или для синтеза маленьких заглавных букв, если шрифт не имеет этой функции? Я не могу найти в документации CoreText ничего, что говорит о маленьких заглавных буквах, хотя есть средства для работы с вариациями/функциями шрифта. Кто-нибудь делал что-нибудь подобное этому?
Поддерживает ли CoreText малые заглавные буквы?
Ответы (5)
Обычно проще всего использовать CTFontDescriptorCreateCopyWithFeature
. Как вы упомянули в своем собственном ответе, это будет работать только для шрифтов, которые действительно реализуют запрашиваемую вами функцию.
CTFontDescriptorCreateCopyWithFeature
немного проще в использовании.
- person Lily Ballard; 27.01.2011
Ответ, по-видимому, является квалифицированным Да. Он поддерживает шрифты с функцией малых заглавных букв, но не поддерживает синтез малых заглавных букв в шрифтах, не имеющих этой функции. Эту функцию можно включить, создав CTFontDescriptor
с атрибутом kCTFontFeatureSettingsAttribute
, который сопоставляется с массивом словарей функций. Клавиша kCTFontFeatureTypeIdentifierKey
должна быть установлена на 3 для регистра букв, а kCTFontFeatureSelectorIdentifierKey
должна быть установлена на 3 для малых заглавных букв. <ATS/SFNTLayoutTypes.h>
содержит константы, идентифицирующие различные значения, хотя этот заголовок недоступен в iOS SDK.
Из шрифтов, доступных на iPad, следующие поддерживают малые прописные:
- HoeflerText-Regular
- HoeflerText-курсив
- HoeflerText-черный
- HoeflerText-черный курсив
- Дидо
Обратите внимание, шрифты Italic/Bold в семействе Didot не поддерживают маленькие заглавные буквы.
Я решил ответить здесь, чтобы предоставить более полное решение для тех, кто пытается решить эту проблему, поскольку информация здесь неполная.
В этом решении используется iOS 7 UIFontDescriptor
, так как я отказываюсь от поддержки iOS 6.
Как указал Энтони Маттокс, значения системного шрифта (которые указаны как 3 и 3, но следует отметить, что на самом деле это kLetterCaseType
и kSmallCapsSelector
, вы не должны ссылаться на перечисление по его номеру) не будут работать для пользовательских шрифтов. Я не уверен, относится ли это ко всем пользовательским шрифтам или только к некоторым, но я обнаружил, что это относится к моему.
Изучив объявление обоих этих значений перечисления, вы можете увидеть, что они в любом случае устарели и, по-видимому, работают только для нескольких системных шрифтов, поддерживающих маленькие заглавные буквы. После регистрации доступных атрибутов для моего пользовательского шрифта, как описано Энтони, я нашел 2 правильных атрибута для использования для пользовательских шрифтов. Это kLowerCaseType
и kLowerCaseSmallCapsSelector
. Я считаю, что эта комбинация — единственный другой вариант, поэтому для любого шрифта, который вы пытаетесь использовать, будет либо тот, либо другой.
Я написал несколько методов категории, чтобы инкапсулировать эту функциональность для обоих случаев:
- (UIFont *) smallCapSystemFont
{
UIFontDescriptor *descriptor = [self fontDescriptor];
NSArray *array = @[@{UIFontFeatureTypeIdentifierKey : @(kLetterCaseType),
UIFontFeatureSelectorIdentifierKey : @(kSmallCapsSelector)}];
descriptor = [descriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute : array}];
return [UIFont fontWithDescriptor:descriptor size:0];
}
- (UIFont *) smallCapCustomFont
{
UIFontDescriptor *descriptor = [self fontDescriptor];
NSArray *array = @[@{UIFontFeatureTypeIdentifierKey : @(kLowerCaseType),
UIFontFeatureSelectorIdentifierKey : @(kLowerCaseSmallCapsSelector)}];
descriptor = [descriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute : array}];
return [UIFont fontWithDescriptor:descriptor size:0];
}
Вы используете их, создавая шрифт с правильным именем и размером, а затем вызывая для него один из этих методов, который возвращает версию этого шрифта с маленькой заглавной буквой. Вам нужно будет выяснить, какой правильный метод использовать для любого шрифта с маленькими заглавными буквами, который вы решите использовать.
Вероятно, существует умный способ выяснить, какой из них использовать программно во время выполнения, проверяя доступные типы (даже просто анализируя результаты этого массива свойств шрифта), но я не удосужился сделать это, поскольку я использую только несколько разные шрифты и ручная проверка мне подходит.
Изменить:
Я заметил одну вещь: числа обрабатываются отдельно. Если вы хотите, чтобы числа также были маленькими (которые на самом деле, кажется, называются «цифрами в старом стиле» в случае большинства шрифтов, которые его поддерживают), вам понадобится это явно как атрибут.
Похоже, это одинаково как для поддержки системных шрифтов, так и для пользовательских шрифтов, в отличие от букв.
Вы просто добавили бы этот словарь в каждый из массивов выше:
@{UIFontFeatureTypeIdentifierKey : @(kNumberCaseType),
UIFontFeatureSelectorIdentifierKey : @(kLowerCaseNumbersSelector)}
Опять же, чтобы это работало, сам шрифт должен поддерживать этот атрибут.
smallCapsSystemFont
с ним, и вы увидите его в действии.
- person Dima; 04.03.2014
CTFontCopyFeatures
). Здесь будут перечислены свойства данного шрифта, и вы сможете увидеть, является ли капитель одним из них. (будет очевидно, какой именно)
- person Dima; 05.03.2014
Чтобы расширить ответ Кевина Балларда. Значения «3» и «3» подходят для системных шрифтов, но не кажутся универсальными. Я использую внешний шрифт, и эти значения не работают.
Вы можете выйти из всех доступных свойств примерно так:
UIFont *font = [UIFont fontWithName: fontName size: fontSize];
CFArrayRef fontProperties = CTFontCopyFeatures ( ( __bridge CTFontRef ) font ) ;
NSLog(@"properties = %@", fontProperties);
CFRelease(fontProperties);
и определите, какая функция шрифта и селектор вам понадобятся, чтобы включить маленькие заглавные буквы или другие функции шрифта.
Поскольку здесь никто не предоставил пример Swift 4, я просто включу код игровой площадки для отображения текста с маленькими заглавными буквами в UILabel:
//: Playground - noun: a place where people can play
import UIKit
import CoreGraphics
let pointSize : CGFloat = 24
let fontDescriptor = UIFont(name: "HoeflerText-Regular", size: pointSize)!.fontDescriptor
let fractionFontDesc = fontDescriptor.addingAttributes(
[
UIFontDescriptor.AttributeName.featureSettings: [
[
UIFontDescriptor.FeatureKey.featureIdentifier: kLetterCaseType,
UIFontDescriptor.FeatureKey.typeIdentifier: kSmallCapsSelector
]
]
] )
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 500, height: 100))
label.font = UIFont(descriptor: fractionFontDesc, size:pointSize)
label.text = "Montpelier, Vermont"