将 TTF 字体文件编码/序列化为 NSData

Encoding / Serializing TTF Font file to NSData

我正在尝试使用 mattt 的 UIFontSerialization class (here) 将一些 UIFont 对象转换为 NSData,以便能够序列化它们并将它们保存在 CoreData 或 Realm 数据库中,但我觉得它不会做我需要的事情。

我正在尝试自己序列化 ttf 文件(我从 API 收到),这样我就不需要将它们存储在用户的文档目录或任何地方。这个想法是我的数据库存储渲染字体所需的一切。

我在使用 CTFontCopyTableCTFontRef 转换为 CFDataRef 时 运行 撞墙了。我正在这样做:

UIFont *originalFont = [UIFont fontWithName:@"Geometos" size:48];
CTFontRef fontRef = CTFontCreateWithName((__bridge CFStringRef)originalFont.fontName, originalFont.pointSize, NULL);
CFDataRef dataRef = CTFontCopyTable(fontRef, kCTFontTableCFF, kCTFontTableOptionNoOptions);
NSData *encodedFont = (__bridge_transfer NSData *)dataRef;

originalFont 很好,在我的包中显示在标签中等。fontRef 也已正确创建,不用担心。 dataRef 最终为零。如果我将 table 标签从 CFF 切换到其他东西,它会编码,但稍后当我将它解码回 UIFont 时,它会失败,所以我认为我需要使用 CFF table(我不知道 CFF 代表什么)。

有人做过吗?将字体存储为序列化数据?

相反,您可以将 fontNamefontSize 存储在数据库中,并在从数据库中获取后使用这些值创建 NSFont .

UIFont *font = [UIFont fontWithName:fontName size:fontSize];

试试这个。

UIFont *originalFont = [UIFont fontWithName:@"Arial" size:48];//Geometos
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:originalFont];
NSFont *font = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"font:%@",font);

好的,我已经设法让它工作了,与 Realm 数据库集成,它非常活泼!

简而言之,我从 API 中获取 ttf,将响应中的原始数据作为 NSData 存储在我的 Realm 数据库中,检索它,然后使用以下命令将其转换为 UIFont 实例的方法:

- (UIFont *)fontWithData:(NSData *)data size:(CGFloat)size {
    NSDate *before = [NSDate date];
    [UIFont familyNames]; // This prevents a known crash in CGDataProviderCreateWithCFData 
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithCFData((CFDataRef)data);
    CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
    NSString *newFontName = (__bridge NSString *)CGFontCopyPostScriptName(newFont);
    CGDataProviderRelease(fontDataProvider);
    CFErrorRef error;
    CTFontManagerRegisterGraphicsFont(newFont, &error);
    CGFontRelease(newFont);
    self.timeTakenToConvert = [[NSDate date] timeIntervalSinceDate:before];
    return [UIFont fontWithName:newFontName size:size];
}

觉得可行! :)