CoreText是否支持Small Caps?

时间:2011-01-26 21:48:01

标签: ios core-text

如果字体没有该功能,CoreText是否可以选择字体的SmallCaps变体或合成小字幕?我在CoreText文档中找不到任何关于小型大写的内容,尽管有处理字体变体/功能的工具。有人做过类似的事吗?

5 个答案:

答案 0 :(得分:10)

答案似乎是合格的是。它支持具有小型大写字母功能的字体,但不支持在没有该功能的字体中合成小型大写字母。可以通过创建具有CTFontDescriptor属性的kCTFontFeatureSettingsAttribute来启用此功能,该属性映射到功能序列数组。对于Letter Case,kCTFontFeatureTypeIdentifierKey键必须设置为3,对于Small Caps,kCTFontFeatureSelectorIdentifierKey必须设置为3。 <ATS/SFNTLayoutTypes.h>包含标识各种值的常量,但iOS SDK中没有此标头。

在iPad上可用的字体中,以下支持Small Caps:

  • HoeflerText正规
  • HoeflerText-斜体
  • HoeflerText黑
  • HoeflerText-BlackItalic
  • 狄多

请注意,Didot系列中的Italic / Bold字体不支持小型大写。

答案 1 :(得分:6)

使用CTFontDescriptorCreateCopyWithFeature通常最简单。正如您在自己的回答中提到的,这仅适用于实际实现您请求的功能的字体。

答案 2 :(得分:5)

我决定在此回答为试图解决此问题的任何人提供更完整的解决方案,因为此处的信息不完整。

此解决方案使用iOS 7 UIFontDescriptor,因为我现在放弃了对iOS 6的支持。

正如Anthony Mattox指出的那样,系统字体值(列为3和3但应注意实际为kLetterCaseTypekSmallCapsSelector,您不应该通过其编号引用枚举),不适用于自定义字体。我不确定这是所有自定义字体的情况还是只是一些,但我发现这是我的情况。

当深入研究这两个枚举值的声明时,您实际上可以看到它们已被弃用,并且可能仅适用于支持小型大写的少数系统字体。在记录了Anthony所描述的自定义字体的可用属性后,我发现了2个用于自定义字体的正确属性。它们是kLowerCaseTypekLowerCaseSmallCapsSelector。我相信这种组合是唯一的其他选择,因此对于您尝试使用的任何字体,它将是其中一种。

我写了一些类别方法来封装这两种情况的功能:

- (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)}

再一次,为了实现这一点,字体本身实际上需要支持这个属性。

答案 3 :(得分:2)

延长Kevin Ballard的答案。值“3”和“3”适用于系统字体,但似乎不是通用的。我正在使用外部字体,这些值不起作用。

您可以使用以下内容注销所有可用的属性:

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

并确定启用小型大写字母或其他字体功能所需的字体功能和选择器。

答案 4 :(得分:0)

由于此处没有人提供 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"