Core Text框架详细解析(三) —— Core Text总体概览

版本记录

版本号 时间
V1.0 2017.10.21

前言

Core Text框架主要用来做文字处理,是的iOS3.2+OSX10.5+中的文本引擎,让您精细的控制文本布局和格式。它位于在UIKit中和CoreGraphics/Quartz之间的最佳点。接下来这几篇我们就主要解析该框架。感兴趣的可以前面几篇。
1. Core Text框架详细解析(一) —— 基本概览
2. Core Text框架详细解析(二) —— 关于Core Text

Core Text总体概览

Core Text是一种用于布置文本和处理字体的高级,低等级技术。Core Text与Core Graphics(CG)(也称为Quartz)一起工作,这是高速图形渲染引擎,可在OS X和iOS的最底层处理二维成像。

重要提示:Core Text旨在开发更高级别的文本处理框架。一般应用程序开发人员应使用iOS中的Text Kit(请参阅Text Programming Guide for iOS)或OS X中的Cocoa文本系统(请参阅Cocoa Text Architecture Guide)。

Core Text介于文本布局和由更高级别的框架提供的字体支持之间以及Quartz为所有文本和字体框架提供的低级功能。 Quartz框架对字形及其位置起作用。Core Text主要注意的是字符如何映射到字体,并且在调用Quartz来呈现文本之前,它会在关于样式,字体度量和其他属性的信息中起一定作用。 Quartz是在基本级别上绘制字形的唯一方法,而且由于Core Text提供了Quartz直接使用的形式的所有数据,所以结果是高性能的文本渲染。

多线程:可以从多个线程同时调用Core Text函数,前提是客户端不会改变任何参数,例如在线程之间共享的归因属性字符串。


Core Text Is a C-based, Platform-Neutral API - Core Text是基于C语言,平台不限的API

Core TextAPI在iOS和OS X上几乎相同,尽管OS X版本提供了更丰富的字体管理API,包括可变字体集合。但是,当您在平台之间移植代码时,您必须考虑UIKit和AppKit之间的区别。例如,您必须有一个Quartz图形上下文来渲染Core Text生成的字形,并且您在每个平台上获得不同的图形环境。您在iOS中绘制的视图是iOS中的UIView子类和OS X中的NSView子类。您应该注意到,CGRect对象被传递到UIView drawRect:方法,而OSX版本的drawRect:被传递NSRect对象。 (您可以使用OS X中的NSRectToCGRect函数将传入的NSRect对象转换为Core Text函数参数所需的CGRect对象。)

UIView函数UIGraphicsGetCurrentContext返回的图形上下文相对于未修改的Quartz图形上下文(即UIView返回的上下文的起点位于左上角)被翻转,因此您必须重新翻转iOS中的图形上下文但不是在OS X中。有关此技术的代码示例,请参见Listing 2-1

Core Text在可能的情况下使用系统数据类型和服务,并且使用与OS X和iOS中的其他核心框架相关的相同约定。例如,Core Text中许多输入和输出参数使用Core Foundation对象,因此您可以将它们存储在Core Foundation集合类中。 Core Graphics框架提供了Core Text所处理的其他对象,如CGPath对象。


Core Text Objects Are C-Language Opaque Types - Core Text对象是C语言不透明类型

OS X和iOS中的许多低级库都以普通C编写,因为速度快和简单。使用Core Text时,您可以使用一组C函数,如CTFramesetterCreateWithAttributedStringCTFramesetterCreateFrame,而不是Objective-C类和方法。

Core Text Opaque Types - Core Text不透明类型

Core Text布局引擎通常适用于归属字符串(CFAttributedStringRef)和图形路径(CGPathRef)。属性字符串对象封装了一个支持显示文本的字符串,并包括定义字符串中字符的风格方面(例如字体和颜色)的属性(或“属性”)。 Core Text中的排版机制使用属性字符串中的信息来执行字符到字形转换。

图形路径定义文本框的形状。在OS X v10.7和iOS 3.2及更高版本中,路径可以是非矩形的。

CFAttributedString引用类型,CFAttributedStringRef,与其基础对象NSAttributedString自由桥接。这意味着Core Foundation类型可以在与桥接的Foundation对象的函数或方法调用中互换。因此,在您看到NSAttributedString *参数的方法中,您可以传入CFAttributedStringRef,并且在您看到CFAttributedStringRef参数的函数中,可以传入NSAttributedString实例。 (您可能需要将一种类型转换为另一种以抑制编译器警告。)这也适用于NSAttributedString的具体子类。

属性是键值对,用于定义字符串中的字符的样式特征,它们分组在共享相同属性的范围内。属性本身被传递到属性字符串,并使用CFDictionary对象从中检索。要将样式应用于字形运行(CTRUN对象),请创建一个CFDictionary对象以保存要应用的属性,然后创建一个属性字符串,将字典作为参数传递。或者,您可以将属性应用于已存在的CFMutableAttributedString对象。虽然CFDictionaryRefNSDictionary是免桥接的,但存储在字典中的各个属性对象可能不是。

Core Text对象在运行时形成层次结构,如图Figure 1-1所示。在这个层次结构的顶部是framesetter对象(CTFramesetterRef)。属性字符串和图片路径作为输入,一个framesetter产生一个或者更多的文本框架CTFrameRef,每个CTFrame对象都代表一个段落

Figure 1-1 Architecture of the Core Text layout engine

要生成frames,framesetter调用一个排版对象(CTTypesetterRef)。当它在一个frame中放置文本时,framesetter将段落样式应用于其中,包括对齐,制表位,行间距,缩进和换行模式等属性。typesetter将属性字符串中的字符转换为字形,并将这些字形填充文本框的行。

每个CTFrame对象都包含段落的行(CTLine)对象。每行对象都代表文本行。 CTFrame对象可能只包含一个长的CTLine对象,也可能包含一组行。线条对象是在framesetting操作期间由typesetter创建,比如,frames,它们可以直接绘制到图形上下文中。

每个CTLine对象包含一个字形运行(CTRun)对象的数组。字形运行是一组共享相同属性和方向的连续字形。typesetter创建字形运行,因为它从字符串,属性和字体对象生成线。这意味着line由一个或多个字形运行构成。如果需要,字形运行可以自己在图形上下文进行绘制,尽管大多数客户端不需要直接与字形运行交互。

Font Objects - 字体对象

字体提供了相对于彼此设计字形的帮助,并且用于在绘制图形上下文时建立当前字体。 Core Text字体不透明类型CTFont是封装大量信息的特定字体实例。其引用类型CTFontRef与iOS中的UIFont和OS X中的NSFont进行自由桥接。当你创建CTFont对象时,这通常指定(或使用默认值)点大小和转换矩阵,这样可以给出字体实例特定的特征。然后,您可以在字体对字形映射,编码,字体度量数据和字形数据等查询字体对象的特定点大小的多种类型的信息。字体指标是诸如上升,下降,前导,上限高度,x-height等参数。字形数据包括诸如边界矩形和字形高级的参数。

Core Text字体对象是不可变的,因此可以通过多个操作,工作队列或线程同时使用。有很多方法来创建字体对象。首选方法是使用CTFontCreateWithFontDescriptor的字体描述符。您还可以使用多种转换API,具体取决于您的开始情况。例如,您可以使用PostScript名称(CTFontCreateWithName)或Core Graphics字体引用(CTFontCreateWithGraphicsFont)。还有CTFontCreateUIFontForLanguage,它为您使用的本地化中的应用程序的用户界面字体创建了一个引用。

Core Text字体引用提供了一种复杂的自动字体替换机制,称为font cascading,它可以选择适当的字体来替代缺少的字体,同时考虑font traitsfont cascading基于cascade lists,它们是有序字体描述符的数组。有一个系统默认级联列表(它是多态的,基于用户的语言设置和当前字体)以及在字体创建时指定的字体级联列表。使用字体描述符中的信息,级联机制可以根据样式和匹配字符匹配字体。CTFontCreateForString函数使用级联列表来选择适当的字体来编码给定的字符串。要指定和检索字体级联列表,请使用kCTFontCascadeListAttribute属性。

Font Descriptors - 字体描述符

CTFontDescriptor不透明类型表示的字体描述符提供了一种完全从属性字典描述字体的机制,以及用于构建新字体的易于使用的字体匹配工具。您可以使用字体描述符创建字体对象,您可以从字体对象获取描述符,您可以更改描述符并使用它来创建一个新的字体对象。您可以通过创建一个字体描述符来部分描述一个字体,例如只有一个姓氏或体重,然后可以找到系统上匹配给定特征的所有字体。 CTFontDescriptorRef类型是自由桥接到iOS中的UIFontDescriptor和OS X中的NSFontDescriptor

您可以创建一个字体属性的字典,其中包括诸如PostScript名称,字体系列和样式之类的属性,以及作为CTFontDescriptor对象的特征(例如,粗体或斜体),而不是处理一个复杂的转换矩阵,您可以使用字体描述符来创建一个CTFont对象。字体描述符可以序列化并存储在一个文件中以提供字体的持久化,下图说明了如何使用一个字体描述符创建一个指定字体实例的字体系统。

Figure 1-2 Creating a font from a font descriptor

您可以将字体描述符视为字体系统中的查询。您可以创建具有不完整规范的字体描述符,即,在属性字典中使用一个或仅仅几个值,并且系统将从可用的字体中选择最合适的字体。例如,如果您使用标准面(标准,粗体,斜体,粗斜体)的家族名称描述符进行查询,则不指定任何特征将匹配系列中的所有成员,但如果指定特征字典与kCTFontTraitBoldkCTFontTraitsAttribute,结果进一步从整个家族成员缩小到满足粗体特征的成员。系统可以通过 CTFontDescriptorCreateMatchingFontDescriptors为您提供与查询匹配的字体描述符的完整列表。

在iOS 6.0及更高版本中,应用程序可以使用CTFontDescriptorMatchFontDescriptorsWithProgressHandler函数根据需要下载未安装的可用字体。以这种方式下载的字体不会永久安装,系统在某些情况下可能会删除它们。可用于下载的字体在iOS 6: Font listiOS 7: Font list中列为“附加信息”:字体列表和iOS 7:字体列表。 DownloadFont (在iOS开发库中)演示了下载技术。 OS X中不需要下载字体,因为所有可用的字体都随系统一起安装。

Font Collections - 字体集合

字体集合是用作单个对象的字体描述符组。字体集合由CTFontCollection不透明类型表示。字体集合提供字体枚举,访问全局和自定义字体集合以及访问包含集合的字体描述符的功能。例如,您可以通过调用CTFontCollectionCreateFromAvailableFonts来创建系统中可用的所有字体的字体集合,您可以使用该集合来获取所有成员字体描述符的数组。

后记

未完,待续~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容