Поддерживает ли CoreText малые заглавные буквы?

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


person Lily Ballard    schedule 26.01.2011    source источник


Ответы (5)


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

person Ned Holbrook    schedule 27.01.2011
comment
В моем случае мне также необходимо дополнительно поддерживать курсив/жирный шрифт, поэтому мне нужно использовать более общую версию атрибутов. Но вы правы, для простого включения/выключения маленьких заглавных букв 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 не поддерживают маленькие заглавные буквы.

person Lily Ballard    schedule 26.01.2011
comment
Я думаю, что этот заголовок теперь доступен в iOS 5 SDK. - person Alastair Stuart; 24.01.2012

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

В этом решении используется 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)}

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

person Dima    schedule 04.02.2014
comment
Этот метод не работает для системного шрифта iOS 7 (Helvetica Neue). - person Legoless; 04.03.2014
comment
@Legoless Чтобы уточнить, это не сработает для Helvetica Neue, потому что этот шрифт не имеет режима малых заглавных букв. Это будет работать только для шрифтов, в которые он встроен. Список этих шрифтов есть в другом ответе на этот вопрос. Примером системного шрифта, с которым он будет работать, является Didot. Попробуйте smallCapsSystemFont с ним, и вы увидите его в действии. - person Dima; 04.03.2014
comment
Если вы хотите использовать маленькие заглавные буквы в Helvetica Neue, вам нужно будет либо найти версию шрифта, созданного кем-то другим, в который он встроен, либо подделать его, нарисовав заглавные буквы меньшего размера. - person Dima; 04.03.2014
comment
Ответ, в котором упоминаются эти шрифты, относится к 2011 году, я думаю, что с тех пор шрифты могли измениться. Но, согласно моим исследованиям, и в OS X, и в iOS используется один и тот же шрифт Helvetica Neue. Так почему же Photoshop может легко отображать маленькие заглавные буквы в Helvetica Neue, а iOS не может? - person Legoless; 05.03.2014
comment
У меня нет на это ответа. Возможно, шрифт на самом деле другой или Photoshop включает собственный шрифт. Вы можете просто запустить тест самостоятельно. Зарегистрируйте свойства шрифта в своем приложении, используя код в ответе выше моего, чтобы увидеть, какие шрифты имеют маленькие заглавные буквы, а какие нет. Вы получите хороший обзор каждого свойства шрифта и сможете увидеть, какие атрибуты доступны, а какие нет. - person Dima; 05.03.2014
comment
Проведение некоторых исследований показывает мне, что продукты Adobe также имитируют маленькие заглавные буквы в некоторых случаях, так что это может быть просто подделкой. Кажется, что он будет использовать маленькие заглавные буквы, если шрифт содержит их, и просто имитирует их в противном случае, что, к сожалению, не отображается для пользователя. graphicdesign.stackexchange.com/questions/15596/ - person Dima; 05.03.2014
comment
Хорошая точка зрения. Итак, что мы должны сделать сейчас, это то же самое, что делает Photoshop. Используйте трюк со строкой с атрибутами. Как бы вы проверили, поддерживает ли шрифт маленькие заглавные буквы изначально? Я полагаю, используя CoreText? - person Legoless; 05.03.2014
comment
Еще раз вы можете использовать функцию ведения журнала в ответе выше этого (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);

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

person Anthony Mattox    schedule 11.10.2013

Поскольку здесь никто не предоставил пример 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" 
person Glenn Howes    schedule 10.01.2018