diff --git a/_posts/2013/2013-03-11-core-text.md b/_posts/2013/2013-03-11-core-text.md index 2c2c206..7599b91 100644 --- a/_posts/2013/2013-03-11-core-text.md +++ b/_posts/2013/2013-03-11-core-text.md @@ -8,7 +8,15 @@ tags: - iOS --- +> 本文所涉及的代码你可以在这里下载到 [https://github.com/kejinlu/CTTest](https://github.com/kejinlu/CTTest),包含两个项目,一个Mac的NSTextView的测试项目,一个iOS的Core Text的测试项目 + + + + ##NSTextView和Attribued String + +---- + 第一次接触苹果系的富文本编程是在写Mac平台上的一个输入框的时候,输入框中的文字可以设置各种样式,并可以在文字中间插入图片,好在Mac的AppKit中提供了NSTextView这个支持富文本编辑器控件。此控件背后是通过什么方式来描述富文本的呢?答案是NSAttributedString,很多编程语言都提供了AttributedString的概念。NSAttributedString比NSString多了一个Attribute的概念,一个NSAttributedString的对象包含很多的属性,每一个属性都有其对应的字符区域,在这里是使用NSRange来进行描述的。下面是一个NSTextView显示富文本的例子 {% highlight objc %} @@ -60,6 +68,9 @@ Printing description of attributedString: 这个时候你就得使用Core Text了。 ##Core Text + +----- + 下面讨论的Core Text相关编程都是特指在iOS平台下。 Core Text是和Core Graphics配合使用的,一般是在UIView的drawRect方法中的Graphics Context上进行绘制的。 且Core Text真正负责绘制的是文本部分,图片还是需要自己去手动绘制,所以你必须关注很多绘制的细节部分。 @@ -108,7 +119,7 @@ Roman Ligatures } 这是非retina分辨率下的结果,如果是如果是retina上面的a,d,ty的值将会乘2,如果是iPhone 5,ty的值会再大些。 -但是作用都是一样的就是将上下文空间坐标系进行了flip,使得原本左下角原点变到左上角,y轴放下也变成向下。 +但是作用都是一样的就是将上下文空间坐标系进行了flip,使得原本左下角原点变到左上角,y轴正方向也变换成向下。 上面说了一大堆,下面进入正题,Core Text一开始便是定位于桌面的排版系统,使用了传统的原点在左下角的坐标系,所以它在绘制文本的时候都是参照左下角的原点进行绘制的。 但是iOS的UIView的drawRect方法的context被做了次flip,如果你啥也不做处理,直接在这个context上进行Core Text绘制,你会发现文字是镜像且上下颠倒。 @@ -120,8 +131,8 @@ Roman Ligatures ####3.NSMutableAttributedString 和 CFMutableAttributedStringRef -Core Foundation和Foundation中的数据类型是可以互换使用的,这类类型我们叫他们为[Toll-Free Bridged Types](http://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html)。 -CFMutableAttributedStringRef和NSMutableAttributedString就是其中的一对,Core Foundation的接口基本是C的接口,功能强大,但是使用起来没有Foundation中提供的Objc的接口简单好使,所以很多时候我们可以使用高层接口组织数据,然后将其传给低层函数使用。 +Core Foundation和Foundation中的有些数据类型只需要简单的强制类型转换就可以互换使用,这类类型我们叫他们为[Toll-Free Bridged Types](http://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html)。 +CFMutableAttributedStringRef和NSMutableAttributedString就是其中的一对,Core Foundation的接口基本是C的接口,功能强大,但是使用起来没有Foundation中提供的Objc的接口简单好使,所以很多时候我们可以使用高层接口组织数据,然后将其传给低层函数接口使用。 ###二.Core Text对象模型 这节主要来看看Core Text绘制的一些细节问题了,首先是Core Text绘制的流程: @@ -134,7 +145,7 @@ CFMutableAttributedStringRef和NSMutableAttributedString就是其中的一对, - CTLine 可以看做Core Text绘制中的一行的对象 通过它可以获得当前行的line ascent,line descent ,line leading,还可以获得Line下的所有Glyph Runs - CTRun 或者叫做 Glyph Run,是一组共享想相同attributes(属性)的字形的集合体 -上面说了这么多对也没一个东西和图片绘制有关系,其实吧,Core Text本身并不支持图片绘制,图片的绘制你还得通过Core Graphics来进行。只是Core Text可以通过CTRun的设置为你的图片在文本绘制的过程中留出适当的空间。这个设置就使用到CTRunDelegate了,看这个名字大概就可以知道什么意思了,CTRunDelegate作为CTRun相关属性或操作扩展的一个入口,使得我们可以对CTRun做一些自定义的行为。所以为图片留位置的方法就是加入一个空白的CTRun,自定义其ascent,descent,width等参数,使得绘制文本的时候留下空白位置给相应的图片。然后图片在相应的空白位置上使用Core Graphics接口进行绘制。 +上面说了这么多对也没一个东西和图片绘制有关系,其实吧,Core Text本身并不支持图片绘制,图片的绘制你还得通过Core Graphics来进行。只是Core Text可以通过CTRun的设置为你的图片在文本绘制的过程中留出适当的空间。这个设置就使用到CTRunDelegate了,看这个名字大概就可以知道什么意思了,CTRunDelegate作为CTRun相关属性或操作扩展的一个入口,使得我们可以对CTRun做一些自定义的行为。为图片留位置的方法就是加入一个空白的CTRun,自定义其ascent,descent,width等参数,使得绘制文本的时候留下空白位置给相应的图片。然后图片在相应的空白位置上使用Core Graphics接口进行绘制。 使用CTRunDelegateCreate可以创建一个CTRunDelegate,它接收两个参数,一个是callbacks结构体,一个是所有callback调用的时候需要传入的对象。 callbacks的结构体为CTRunDelegateCallbacks,主要是包含一些回调函数,比如有返回当前run的ascent,descent,width这些值的回调函数,至于函数中如何鉴别当前是哪个run,可以在CTRunDelegateCreate的第二个参数来达到目的,因为CTRunDelegateCreate的第二个参数会作为每一个回调调用时的入参。