Подтвердить что ты не робот

Поддерживает ли CoreText Small Caps?

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

  • HoeflerText-Regular
  • HoeflerText-Курсив
  • HoeflerText-черный
  • HoeflerText-BlackItalic
  • Didot

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

Ответ 3

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

Это решение использует 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];
}

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

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

Edit:

Одна вещь, которую я заметил, это то, что числа обрабатываются отдельно. Если вы хотите, чтобы число было слишком маленьким (что на самом деле называется "номера старого стиля" в случае большинства шрифтов, которые его поддерживают), вам нужно будет явно указать его как атрибут.

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

Вы просто добавили бы этот словарь в каждый из приведенных выше массивов:

@{UIFontFeatureTypeIdentifierKey : @(kNumberCaseType),
                         UIFontFeatureSelectorIdentifierKey : @(kLowerCaseNumbersSelector)}

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

Ответ 4

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

Вы можете вывести все доступные свойства с помощью следующего:

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

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

Ответ 5

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