From 8a15975fca06ae3d21890835d32493d574d3ad00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A2=E5=85=8B?= Date: Tue, 19 Mar 2013 14:43:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=87=E7=82=B9=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _posts/2013/2013-03-11-core-text.md | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/_posts/2013/2013-03-11-core-text.md b/_posts/2013/2013-03-11-core-text.md index 6bf788e..2c2c206 100644 --- a/_posts/2013/2013-03-11-core-text.md +++ b/_posts/2013/2013-03-11-core-text.md @@ -8,23 +8,23 @@ tags: - iOS --- -###NSTextView和Attribued String +##NSTextView和Attribued String 第一次接触苹果系的富文本编程是在写Mac平台上的一个输入框的时候,输入框中的文字可以设置各种样式,并可以在文字中间插入图片,好在Mac的AppKit中提供了NSTextView这个支持富文本编辑器控件。此控件背后是通过什么方式来描述富文本的呢?答案是NSAttributedString,很多编程语言都提供了AttributedString的概念。NSAttributedString比NSString多了一个Attribute的概念,一个NSAttributedString的对象包含很多的属性,每一个属性都有其对应的字符区域,在这里是使用NSRange来进行描述的。下面是一个NSTextView显示富文本的例子 {% highlight objc %} NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:@"测试富文本显示"] autorelease]; //为所有文本设置字体 -[attributedString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:24] range:NSMakeRange(0, [attributedString length])]; +[attributedString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:24] range:NSMakeRange(0, [attributedString length])]; //将“测试”两字字体颜色设置为蓝色 -[attributedString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 2)]; +[attributedString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 2)]; //将“富文本”三个字字体颜色设置为红色 -[attributedString addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(2, 3)]; +[attributedString addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(2, 3)]; //在“测”和“试”两字之间插入一张图片 -NSString *imageName = @"taobao。png"; +NSString *imageName = @"taobao.png"; NSFileWrapper *imageFileWrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[[NSImage imageNamed:imageName] TIFFRepresentation]] autorelease]; -imageFileWrapper。filename = imageName; -imageFileWrapper。preferredFilename = imageName; +imageFileWrapper.filename = imageName; +imageFileWrapper.preferredFilename = imageName; NSTextAttachment *imageAttachment = [[[NSTextAttachment alloc] initWithFileWrapper:imageFileWrapper] autorelease]; NSAttributedString *imageAttributedString = [NSAttributedString attributedStringWithAttachment:imageAttachment]; @@ -35,17 +35,17 @@ NSAttributedString *imageAttributedString = [NSAttributedString attributedString Printing description of attributedString: 测{ NSColor = "NSCalibratedRGBColorSpace 0 0 1 1"; - NSFont = "\"LucidaGrande 24。00 pt。 P [] (0x10051bfd0) fobj=0x101e687f0, spc=7。59\""; + NSFont = "\"LucidaGrande 24.00 pt. P [] (0x10051bfd0) fobj=0x101e687f0, spc=7.59\""; }{ NSAttachment = " \"taobao。png\""; }试{ NSColor = "NSCalibratedRGBColorSpace 0 0 1 1"; - NSFont = "\"LucidaGrande 24。00 pt。 P [] (0x10051bfd0) fobj=0x101e687f0, spc=7。59\""; + NSFont = "\"LucidaGrande 24.00 pt. P [] (0x10051bfd0) fobj=0x101e687f0, spc=7.59\""; }富文本{ NSColor = "NSCalibratedRGBColorSpace 1 0 0 1"; - NSFont = "\"LucidaGrande 24。00 pt。 P [] (0x10051bfd0) fobj=0x101e687f0, spc=7。59\""; + NSFont = "\"LucidaGrande 24.00 pt. P [] (0x10051bfd0) fobj=0x101e687f0, spc=7.59\""; }显示{ - NSFont = "\"LucidaGrande 24。00 pt。 P [] (0x10051bfd0) fobj=0x101e687f0, spc=7。59\""; + NSFont = "\"LucidaGrande 24.00 pt. P [] (0x10051bfd0) fobj=0x101e687f0, spc=7.59\""; } */ @@ -53,22 +53,22 @@ Printing description of attributedString: [_textView insertText:attributedString]; {% endhighlight %} -![](http://ww1。sinaimg。cn/bmiddle/65cc0af7gw1e2rnc6to9cj。jpg) +![](http://ww1。sinaimg。cn/bmiddle/65cc0af7gw1e2rnc6to9cj.jpg) 还有就是NSAttributedString提供对所有属性进行遍历的方法,也提供了计算在特定size下渲染实际所占的区域(boundingRectWithSize:options:) 这些这里就不介绍了。 从上面的代码可以看出其实Mac下的富文本的渲染并不是很复杂,只要将Attributed String理解和使用好,其余的事情都交给NSTextView来做了,你完全不用考虑其底层是如何取渲染的。但是在iOS平台上就没有这么幸运了,虽然iOS从3。2开始也提供了NSAttributedString,但是并没有类似NSTextView这样的控件直接来渲染Attributed String。 这个时候你就得使用Core Text了。 -###Core Text +##Core Text 下面讨论的Core Text相关编程都是特指在iOS平台下。 Core Text是和Core Graphics配合使用的,一般是在UIView的drawRect方法中的Graphics Context上进行绘制的。 且Core Text真正负责绘制的是文本部分,图片还是需要自己去手动绘制,所以你必须关注很多绘制的细节部分。 -####一.Core Text知识准备 +###一.Core Text知识准备 在进入任何一个新的编程领域之前,我们肯定要先接触相关的领域模型的知识。比如你软件是进行科学计算的,那么你就必须理解大量的数学原理;如果你的软件是搞银行系统,那么你就得事先了解相关的银行的业务知识。这些都是不可避免的事情。通常情况下领域知识具有较高的通用性。但在特定的环境下,某些知识点也会被特殊处理。 Core Text是用来进行文字精细排版的,所以了解文字相关的知识也不可避免。 -#####1.字符(Character)和字形(Glyphs) +####1.字符(Character)和字形(Glyphs) 排版系统中文本显示的一个重要的过程就是字符到字形的转换,字符是信息本身的元素,而字形是字符的图形表征,字符还会有其它表征比如发音。 字符在计算机中其实就是一个编码,某个字符集中的编码,比如Unicode字符集,就囊括了大都数存在的字符。 而字形则是图形,一般都存储在字体文件中,字形也有它的编码,也就是它在字体中的索引。 @@ -91,7 +91,7 @@ Roman Ligatures 以上图片和部分概念来自苹果文档 [Querying Font Metrics](http://developer.apple.com/library/mac/#documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html#//apple_ref/doc/uid/TP40009459-CH5-SW18) ,[Text Layout](http://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/TypoFeatures/TextSystemFeatures.html#//apple_ref/doc/uid/TP40009459-CH6-51627-BBCCHIFF) -#####2.坐标系 +####2.坐标系 首先不得不说 苹果编程中的坐标系花样百出,经常让开发者措手不及。 传统的Mac中的坐标系的原点在左下角,比如NSView默认的坐标系,原点就在左下角。但Mac中有些View为了其实现的便捷将原点变换到左上角,像NSTableView的坐标系坐标原点就在左上角。iOS UIKit的UIView的坐标系原点在左上角。 往底层看,Core Graphics的context使用的坐标系的原点是在左下角。而在iOS中的底层界面绘制就是通过Core Graphics进行的,那么坐标系列是如何变换的呢? @@ -119,11 +119,11 @@ Roman Ligatures 这里再提及一个函数CGContextSetTextMatrix,它可以用来为每一个显示的字形单独设置变形矩阵。 -#####3.NSMutableAttributedString 和 CFMutableAttributedStringRef +####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 Text对象模型 +###二.Core Text对象模型 这节主要来看看Core Text绘制的一些细节问题了,首先是Core Text绘制的流程: ![](http://ww1.sinaimg.cn/large/65cc0af7gw1e2uxd1gmhwj.jpg) @@ -138,7 +138,7 @@ CFMutableAttributedStringRef和NSMutableAttributedString就是其中的一对, 使用CTRunDelegateCreate可以创建一个CTRunDelegate,它接收两个参数,一个是callbacks结构体,一个是所有callback调用的时候需要传入的对象。 callbacks的结构体为CTRunDelegateCallbacks,主要是包含一些回调函数,比如有返回当前run的ascent,descent,width这些值的回调函数,至于函数中如何鉴别当前是哪个run,可以在CTRunDelegateCreate的第二个参数来达到目的,因为CTRunDelegateCreate的第二个参数会作为每一个回调调用时的入参。 -####三.Core Text实战 +###三.Core Text实战 直接贴上代码大家体会下: