CoreText Part 1

2016-09-27  本文已影响72人  Laughingg

Apple 的相关博客:
Text Programming Guide for iOS
Core Text Programming Guide

CoreText 框架位置

text_kit_arch_2x-2.png

唐巧博客
基于 CoreText 的排版引擎:基础

《Core Text Tutorial for iOS: Making a Magazine App》

使用 CoreText 实现图文混排

基于 CoreText 的开源库
OHAttribtuedLabel
DTCoreText
Nimbus
YYText
M80AttributedLabel

CoreText 引擎的架构

core_text_arch_2x.png

iOS/OSX中用于描述富文本的类是NSAttributedString。NSAttributedString 的 attributes 可以配置字符串中任意区域的,字体颜色,下划线,斜体,背景颜色。

CoreText 中最重要的两个概念就是 CTFrameSetter 和 CTFrame。

  1. 用 NSAttributedString 生成 CTFrameSetter
  2. CTFrameSetter 是 CTFrame 的工厂,专门用来生产 CTFrame(用 CTFrameSetter 来 生产 CTFrame )
  3. 用 CTFrame 绘制到 context 上。
    (CTLine 和 CTRun 是由属性文本自动处理的,要进行精细化配置的时候才需要自己处理 CTRun)

CoreText 的简单使用

使用 CoreText 进行图文混排其实不是最根本的目的。
CoreText 使用,主要是用来显示字符串的。

小目标 —— 显示字符串

下列代码写在一个自定义的 UIView 的子类中。

override func draw(_ rect: CGRect) {
    super.draw(rect)
    
    // 1. 获取当前的图形上下文
    let context = UIGraphicsGetCurrentContext()
    
    // 2. 翻转坐标
    context!.textMatrix = CGAffineTransform.identity
    context!.translateBy(x: 0, y: self.bounds.size.height);
    context!.scaleBy(x: 1.0, y: -1.0);
    
    // 3. 文本绘制的范围
    let path = CGMutablePath()
    // 绘制字符串的范围可以自己通过路径自己指定
    path.addRect(rect)
    
    // 4. 创建属性字符串
    let str: String = "Hello World!"
    let attributedString = NSMutableAttributedString(string: str)
    
    // 5. 创建 framesetter
    let framesetter = CTFramesetterCreateWithAttributedString(attributedString as CFAttributedString )
    
    // 6. 创建 frame
    let frame = CTFramesetterCreateFrame(framesetter, CFRange(location: 0, length: 0), path, nil)
    
    // 7. 绘制
    CTFrameDraw(frame, context!)
}
Snip20160928_12.png

** 文本绘制的过程 **


CoreText_2.png

整个流程大概是:
获取上下文 ——> 翻转坐标系 (翻转坐标主要是由于 UIKit 的坐标系和 CG 框架的坐标系是不一样的 ) ——> 创建 NSAttributedString ——> 根据NSAttributedString创建CTFramesetter ——>创建绘制区域CGPathRef ——> 根据CTFramesetter 和 CGPath 创建 CTFrame ——> CTFrameDraw 绘制。

**CoreText 视窗组合图 **

1363570926_6077-2.png

UIGraphicsGetCurrentContext() 获取的 context 相对于 Quartz ,可以理解为一个画板。
CTFrame 相对于 CoreText , 也可以理解为一个图文画板。最终的目的也就是将 CTFrame 画板上绘制的图文 再绘制到 context 上,显示出来给用户看。

我们要使用 CoreText 的目的还是要控制 CTFrame 画板上图文的绘制。

根据视窗结构图体现,CTFrame 主要有 CTLine 组成, CTLine 又主要由 CTRun 组成。

注意到上面的示例代码,发现我们没有创建 CTLine 和 CTRun,CoreText 会根据 NSAttributedString 的属性来自动创建 CTRun,CTRun 又组合为CTLine, 每个CTRun对象对应不同的属性,正因此,你可以自由的控制字体、颜色、字间距等等信息。

在实际的使用中最终步骤:
创建 NSAttributedString ——> 根据NSAttributedString创建CTFramesetter ——>创建绘制区域CGPath ——> 根据CTFramesetter 和 CGPath 创建 CTFrame ——> CTFrameDraw 绘制。

上一篇下一篇

猜你喜欢

热点阅读