為個(gè)人閱讀快速翻譯, 難免有誤, 見諒, 原文(Apple 文檔)
Core Text 概述
Core Text 是一種強(qiáng)大的底層文本布局和處理字體的技術(shù), Core Text 直接使用 Core Graphics(CG), 通常也叫做 Quartz, 是iOS 和 OSX 底層的高速二維圖像渲染引擎.
注意: Core Text 是為上層文本處理所開發(fā)的框架, 普通開發(fā)者在 iOS 中應(yīng)該使用 Text Kit, OSX 中應(yīng)該使用 Cocoa text system
譯者注: 言外之意就是普通玩家用封裝好的Text Kit, 高玩可嘗試, 不推薦低端用戶使用~
Core Text 協(xié)調(diào)了文本布局, 上層字體框架, Quartz 提供的底層文本和字體框架.
Quartz 框架負(fù)責(zé)字形和位置. Core Text 負(fù)責(zé)從字符到字體的映射, 在調(diào)用Quartz 渲染這些文本之前, 它會(huì)分離出樣式, 字體和其他一些屬性. Quartz 是唯一的底層圖形繪制方法. 因?yàn)?Core Text 已經(jīng)以一定格式提供給Quartz 所有需要的信息. 這樣結(jié)能夠有很高的文本渲染性能.
多線程 : Core Text 支持多線程,是線程安全的, 前提是不在線程之間改變?nèi)魏螀?shù), 比如共享屬性字符串(attributed string)
Core Text 是一系列 C語言平臺(tái)無關(guān)的 API
iOS 和 OS X 平臺(tái)上 Core Text API 基本一致, 到那時(shí) OS X 版本提供了更為豐富的字體管理 API, 包括可變的字體集合. 但是, UIKit 和 AppKit 在不同平臺(tái)上有很大區(qū)別. 比如, 你必須有一個(gè)Quartz圖形上下文來渲染 Core Text 生成的圖形, 和在不同平臺(tái)上獲取的圖像上下文也不一樣. 在 iOS 平臺(tái)上, 一個(gè)視圖對(duì)應(yīng)的是 UIView的子類, 而在 OS X平臺(tái)上, 一個(gè)視圖對(duì)應(yīng)的是NSView 的子類. 你必須清楚, CGRect 對(duì)象傳給 UIView 的 drawRect:方法, 而 OS X 傳遞的是一個(gè)NSRect
對(duì)象. 你可以使用NSRectToCGRect方法來講 NSRect
轉(zhuǎn)換成CGRect
.
圖形上下文由 UIView
的 UIGraphicsGetCurrentContext 方法返回. 這個(gè)上下文是由 Quartz圖形上下文未經(jīng)修改上下翻轉(zhuǎn)過來的(UIView 返回的上下文原點(diǎn)在左上角), 所以在 iOS 中你必須將其翻轉(zhuǎn)過來, OS X 不需要翻轉(zhuǎn), 詳情可以去Listing 2-1 查看一些示例代碼.
譯者注: Quartz 和 OS X 原點(diǎn)在窗口左下角, 而 iOS 的原點(diǎn)在左上角, 所以需要翻轉(zhuǎn)
Core Text 盡可能的使用系統(tǒng)數(shù)據(jù)類型和服務(wù), 所以你也可以使用 OS X 或者 iOS 的核心框架. 比如, Core Text 使用 Core Foundation 對(duì)象作為輸入輸出參數(shù), 所以你當(dāng)然可以將其存到 Core Foundation 集合類里面. 其他Core Text使用的對(duì)象比如 CGPath, 是由 Core Graphics 框架提供.
Core Text 對(duì)象是一系列 C語言不透明類型(Opaque Types)
在 OS X 和 iOS 中, 許多底層庫為了速度和簡(jiǎn)潔,使用了純 C 編寫. 當(dāng)你使用 Core Text 的時(shí), 你使用一系列 C 函數(shù), 比如CTFramesetterCreateWithAttributedString和 CTFramesetterCreateFrame 來替代 Objective-C 類和方法.
Core Text 不透明類型(Opaque Types)
Core Text 布局引擎經(jīng)常跟屬性字符串(CFAttributedStringRef)和圖形路徑(CGPathRef)打交道. 屬性字符串對(duì)象將一個(gè)用于顯示的文本和一些定義格式樣式的屬性封裝起來, 比如字體和顏色. Core Text 使用屬性字符串里的信息來執(zhí)行字符到圖像的轉(zhuǎn)換.
圖形路徑定義一幀文本的形狀. 在 OS X 10.7和 iOS 3.2及更新版本, 這個(gè)路徑可以不是矩形
CFAttributedString
的引用類型 CFAttributedStringRef
, 和 Foundation 中的 NSAttributedString
是 toll-free bridged的. 這就意味著 Core Foundation 類型在函數(shù)或方法中可以和bridged Foundation 對(duì)象互相替換的. 因此, 在一個(gè)方法中, NSAttributedString *
參數(shù)是可以傳入一個(gè)CFAttributedStringRef
類型. 反之, 在CFAttributedStringRef
參數(shù)可以傳入一個(gè)NSAttributedString
實(shí)例(可能需要轉(zhuǎn)換類型來消除編譯器警告) 這個(gè)同樣適用于NSAttributedString
的子類.
屬性本質(zhì)就是一系列鍵值對(duì), 定義部分字符的屬性特征, 使用相同屬性的字符根據(jù)range 進(jìn)行分組. 屬性使用CFDictionary
對(duì)象傳入屬性字符串,而后被取出來. 應(yīng)用一個(gè)樣式到一個(gè)圖像運(yùn)行器(CTRun 對(duì)象), 創(chuàng)建一個(gè)CFDictionary
對(duì)象來存儲(chǔ)你想要應(yīng)用的屬性., 然后創(chuàng)建一個(gè)屬性字符串, 把這個(gè)字典作為參數(shù)傳入. 或者, 你可以應(yīng)用這些屬性到一個(gè)已經(jīng)存在的CFMutableAttributedString
對(duì)象中. 即使CFDictionaryRef
和 NSDictionary
是toll-free bridged, 但字典中存儲(chǔ)的屬性對(duì)象可能并不是.
圖 1-1顯示了Core Text 對(duì)象運(yùn)行時(shí)層級(jí). 最上層是一個(gè)framesetter對(duì)象(CTFramesetterRef). 一個(gè)屬性字符串和一個(gè)圖像路徑作為輸入, framesetter可以生成一個(gè)或多個(gè)幀文本(CTFrameRef). 每個(gè)CTFrame
對(duì)象代表著一個(gè)段落.
framesetter
調(diào)用一個(gè)typesetter
對(duì)象生成 frame, 在 frame 中放置文本, framesetter
將段落樣式應(yīng)用到這個(gè) frame 上, 包括對(duì)齊方式, 制表符, 行間距, 縮進(jìn)和斷句模式. typesetter
將屬性字符串中的字符轉(zhuǎn)換成字形, 并將字形填充到文本框的行中
每個(gè) CTFrame
對(duì)象包括段落的行對(duì)象(CTLine). 每個(gè)行對(duì)象代表著一行文本. 一個(gè) CTFrame
對(duì)象可能只包含一行很長(zhǎng)的CTLine
對(duì)象或者很多行. 在framesetting
操作過程中, 會(huì)創(chuàng)建行對(duì)象. 這些行對(duì)象跟 frame
一樣, 可以直接將自己繪制到圖像上下文中.
每個(gè)行對(duì)象包含一個(gè)數(shù)組的glyph run
(CTRun)對(duì)象. 一個(gè)glyph run
每一行對(duì)象都包含一系列連續(xù)不斷的字形,這些字形都包含相同的屬性和方向. typesetter
會(huì)在從字符產(chǎn)生行時(shí)創(chuàng)建glyph run
對(duì)象. 這就意味著, 一個(gè)行對(duì)象是由一個(gè)或多個(gè)glyphs run
構(gòu)成. glyphs run
可以將自己繪入圖像上下文中, 若非必要時(shí),大多數(shù)客戶端不需要直接跟 glyph run
打交道.
字體對(duì)象
字體對(duì)象為字形之間的布局提供支持, 然后將當(dāng)前字體繪入圖像上下文. Core Text 字體不透明對(duì)象, CTFont, 是一個(gè)特殊的字體實(shí)例, 封裝了許多實(shí)例. CTFontRef
為其引用類型, 和 iOS 中的 UIFont, OS X 的 NSFont 是 oll-free bridged
, 你可以指定字體大小和變換矩陣, 給這字體實(shí)例具體特征. 對(duì)于大小特定的字體, 你可以從字體對(duì)象中查詢到很多關(guān)于字體相關(guān)的信息, 比如字符到字形的映射, 編碼, 字體度量信息, 和字形信息等等. 字體度量是一些參數(shù), 比如, 升序, 降序, 開頭, 頭高等等. 字形信息包含參數(shù)比如, 矩形邊界和字形步進(jìn).
Core Text 字體對(duì)象是不可變的, 所以可以被多個(gè)操作, 工作隊(duì)列或者線程使用. 有很多方式創(chuàng)建字體對(duì)象. 首選方法是從一個(gè)字體描述符創(chuàng)建一個(gè)字體對(duì)象CTFontCreateWithFontDescriptor, 還有其他很多方便的 API, 具體使用哪個(gè)要看你的目的. 比如, 你可以使用字形的 PostScript 名字(CTFontCreateWithName
)或者 一個(gè) Core Graphics 字體引用(CTFontCreateWithGraphicsFont
), CTFontCreateUIFontForLanguage 在所使用的應(yīng)用本地創(chuàng)建一個(gè)用戶接口字體引用.
Core Text 字體引用提供了一個(gè)復(fù)雜的自動(dòng)字體替換機(jī)制, 叫做字體串聯(lián).
根據(jù)字體的特征挑選合適的字體來替換一個(gè)找不到的字體, 字體串聯(lián)基于串聯(lián)的列表, 是一系列有序的字體描述符. 在一個(gè)字體創(chuàng)建的時(shí)候, 會(huì)指定一個(gè)系統(tǒng)默認(rèn)的串聯(lián)列表(根據(jù)用戶的語言設(shè)置和當(dāng)前字體有不同的表現(xiàn))和一個(gè)字體串聯(lián)列表. 串聯(lián)機(jī)制可以使用字體描述符的信息, 根據(jù)樣式為字符匹配字體 CTFontCreateForString 函數(shù)可以使用串聯(lián)列表來挑選合適的字體去編碼對(duì)應(yīng)的字符串. 使用kCTFontCascadeListAttribute 屬性來指定和檢索字體串聯(lián)列表.
字體描述符
字體描述符, 用CTFontDescriptor
不透明類型表示, 提供了完全從一個(gè)屬性字典描述字體的機(jī)制, 和易用的創(chuàng)建新字體的設(shè)施. 你可以根據(jù)字體描述符創(chuàng)建字體, 也可以從一個(gè)字體對(duì)象中獲取字體描述符, 然后用其來創(chuàng)建一個(gè)新的字體對(duì)象. 你可以創(chuàng)建字體描述符來部分創(chuàng)建字體, 比如, 只是字體簇名稱或者比重, 然后就可以找到系統(tǒng)中與之匹配的所有字體.iOS 中的UIFontDescriptor
, OS X 中的NSFontDescriptor
與 CTFontDescriptorRef
類型是toll-free bridged
.
我們使用創(chuàng)建一個(gè)包含PostScript 名字, font family, 樣式以及其他特性(比如, 粗體或斜體)等的字體屬性字典來作為CTFontDescriptor
對(duì)象. 你可以使用字體描述符創(chuàng)建一個(gè)CTFont
對(duì)象. 字體描述符可以被序列化并存儲(chǔ)到文檔中來進(jìn)行持久化.
圖 1- 2描述了字體系統(tǒng)使用字體描述符創(chuàng)建指定字體實(shí)例
你可以認(rèn)為字體描述符就是字體系統(tǒng)中的查詢條件, 你可以創(chuàng)建一個(gè)不完整的字體描述符, 屬性字典里只是一部分的值. 比如, 如果你指定了 font family, 不指定字體的所有特性, 你就能獲取到該 font family 的所有字體, 但是如果你指定了kCTFontTraitsAttribute
的值為kCTFontTraitBold
, 那么就能查詢到該 font family 下的所有粗體. 通過CTFontDescriptorCreateMatchingFontDescriptors提供可以提供一個(gè)跟查詢匹配的完整的字體描述符列表.
在 iOS 6.0及以后版本, 應(yīng)用可以使用CTFontDescriptorMatchFontDescriptorsWithProgressHandler
下載所需未安裝的字體, 下載的字體并不是安裝后永遠(yuǎn)不變的, 系統(tǒng)可能會(huì)在一定情況下將其移除, 支持下載的字體被列在iOS 6: Font list 和iOS 7: Font list. DownloadFont(在 iOS 開發(fā)庫中)說明了下載技術(shù). 在 OS X 中, 按需下載字體不是必須的, 因?yàn)樗锌捎米煮w都已經(jīng)安裝到系統(tǒng)中了.
字體集合
字體集合是一系列字體組成的組作為一個(gè)單獨(dú)的對(duì)象. CTFontCollection
不透明來行代表一個(gè)字體集合. 字體集合提供字體枚舉, 訪問全局和自定義字體集合, 以及訪問包含該字體集合的字體描述符的能力. 舉個(gè)例子, 通過CTFontCollectionCreateFromAvailableFonts創(chuàng)建一個(gè)包含所有可用字體描述符的集合, 你可以使用這個(gè)集合獲取所有字體描述符.
.