CoreText поддерживает маленькие заглавные буквы? - PullRequest
13 голосов
/ 27 января 2011

Есть ли в CoreText какие-либо средства для выбора варианта шрифта SmallCaps или для синтеза маленьких заглавных букв, если у шрифта такой функции нет?Я не могу найти ничего в документации CoreText, в которой говорится о маленьких заглавных буквах, хотя есть средства для работы с вариантами шрифтов / функциями.Кто-нибудь делал что-нибудь подобное?

Ответы [ 5 ]

10 голосов
/ 27 января 2011

Ответ представляется квалифицированным Да. Он поддерживает шрифты, которые имеют функцию малых заглавных букв, но не поддерживает синтез маленьких заглавных букв в шрифтах, которые не имеют этой функции. Эту функцию можно включить, создав CTFontDescriptor с атрибутом kCTFontFeatureSettingsAttribute, который сопоставляется с массивом функций. Клавиша kCTFontFeatureTypeIdentifierKey должна быть установлена ​​на 3 для буквенного регистра, а клавиша kCTFontFeatureSelectorIdentifierKey должна быть установлена ​​на 3 для маленьких букв. <ATS/SFNTLayoutTypes.h> содержит константы, которые определяют различные значения, хотя этот заголовок недоступен в iOS SDK.

Из шрифтов, доступных на iPad, следующая поддержка Small Caps:

  • HoeflerText-Regular
  • HoeflerText-Italic
  • HoeflerText-черный
  • HoeflerText-BlackItalic
  • Didot

Обратите внимание: шрифты Italic / Bold в семействе Didot не поддерживают маленькие заглавные буквы.

6 голосов
/ 27 января 2011

Обычно проще всего использовать CTFontDescriptorCreateCopyWithFeature.Как вы упомянули в своем собственном ответе, это будет работать только для шрифтов, которые фактически реализуют запрашиваемую вами функцию.

5 голосов
/ 04 февраля 2014

Я решил ответить здесь, чтобы предоставить более полное решение для всех, кто пытается решить эту проблему, поскольку информация здесь неполная.

В этом решении используется iOS 7 UIFontDescriptor, так как сейчас я прекращаю поддержкудля iOS 6.

Как указал Энтони Мэттокс, значения системных шрифтов (которые указаны как 3 и 3, но следует отметить, что на самом деле это kLetterCaseType и kSmallCapsSelector, не следует ссылаться на enumпо его номеру), не будет работать для пользовательских шрифтов.Я не уверен, так ли это для всех пользовательских шрифтов или только для некоторых, но я обнаружил, что это так и с моими.

При копировании в объявление обоих этих значений перечисления вы можете увидеть, что они все равно устарели и предположительно работают только для тех немногих системных шрифтов, которые поддерживают маленькие заглавные буквы.После регистрации доступных атрибутов для моего настраиваемого шрифта, как описано Энтони, я нашел 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)}

Еще раз, чтобыработать сам шрифт фактически должен поддерживать этот атрибут.

2 голосов
/ 11 октября 2013

Чтобы расширить ответ Кевина Балларда. Значения «3» и «3» работают для системных шрифтов, но не кажутся универсальными. Я использую внешний шрифт, и эти значения не работают.

Вы можете выйти из всех доступных свойств следующим образом:

UIFont *font = [UIFont fontWithName: fontName size: fontSize];
CFArrayRef  fontProperties  =  CTFontCopyFeatures ( ( __bridge CTFontRef ) font ) ;
NSLog(@"properties = %@", fontProperties);
CFRelease(fontProperties);

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

0 голосов
/ 10 января 2018

Поскольку здесь никто не предоставил образец 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" 
...