原文地址:http://www.bignerdranch.com/blog/core-graphics-part-1-in-the-beginning/
Mac和iOS为开发者提供了许多不同的API用于用户界面的开发。UIKit和AppKit库都拥有很多image,color和path类。Core Animation提供了layer层展示的API。使用OpenGL可以渲染3-D画面。Spritekit可以实现一些列动画。AVFoundation提供了播放视频/音频的接口。
Core Graphic又被称作“Quartz”,它是一个早期被被用来在系统中实现一系列图形相关的API库。Quartz是2-D画面渲染的基础。用Core Graphic库可以实现各种图形,形状的绘制,填充,阴影效果,还能合成图像,创建PDF文件。可见功能非常强大。
CG(Core Graphic)是一个相当大的图形API库,包括基本的几何图形元素(点,大小,矢量和矩形等),还能对这些元素进行操作,渲染图像中的元素,所有这些都是通过事件处理来完成的。你可以创建“Tap事件”,用来监听交互事件(鼠标点击,屏幕触控和键盘输入)。
看到上面这些介绍,比较困惑的就是为什么图形API可以处理用户事件?这些都是历史遗留问题。如果对这些历史有所了解就能理解为什么CG是这么设计的。
让我们把时间倒回到1980年,当年邓丽君还在风风火火。当时的图形API跟今天的比起来还很小儿科。那时的API提供的功能也有限,你只能从很少的颜色中选取一种,然后画画线,画画图形,你还能通过一个个的像素点来组成一个图形。当时Mac上有一个叫做AuickDraw的软件,能完成一些比较酷的操作,它能画出不规则的图形,并实现填充,剪切等功能。但说到头来,这些API还都是停留在对像素进行操作。
1985年,苹果开发出了一款兼做激光打印机的设备,这个设备比当时的计算机价格要高出两倍。这个打印机中安装了一个微处理器器,比电脑上的强大的多。这个打印机依靠了一种叫做PostScript的技术,能打印出非常漂亮的图片。
PostScript是由Adobe发明的一种基于堆栈的编程语言,和FORTH很相似。通过PostScript技术可以创建矢量图形(使用数学公式进行描述的图形),而不是通过像素这种方式。激光打印机中有一个用来解释PostScript的处理器,当需要打印图形的时候,可以现在Mac中编好程序,然后下载到打印机中,就可以开始打印了。
下面有一张关于PostScript的Demo,左边是程序,右边是效果:
你可以在 github 中下载该项目。
将图像用程序来进行表示,是一个非常天才的设计。程序可以通过编写特定的算法来描述图形,这样的好处的就是通过这些算法,可以输出任意精度的分辨率图形。不管是300dpi还是1200dpi都是用的同一套代码。
PostScript不光可以用来渲染图像,它其实就是一个编程语言,可以用来设计web server。
当NeXT的工程师在设计他们的系统的时,他们选择了PostScript作为渲染模型。他们拓展了PostScript模型(DPS),并使其可以在屏幕上显示出来,而不仅仅是通过打印机输出,但是核心还是PostScript技术。NeXT设计出的程序可以在屏幕显示和打印机输出上使用同一个代码,并且还能将PostScript嵌入到C程序中。
DPS是用户界面的基础,事件响应(鼠标,键盘等)也一并通过DPS集成到了软件中。
除了NeXT系统之外,Sun公司的NeWS系统也是使用的PostScript技术来驱动用户界面系统的。
前面说了这么多,但为什么Mac和iOS不是用的PostScript呢?因为,钱!Adobe持有PostScript的版权,凡是使用者都要交版权费。而且,苹果还有一个特点就是,它希望自己能掌握核心技术,而不是使用别人的。他们实现了和PostScript同等功能的技术,这样可以避免交版权税,还能拥有自己的core graphic代码。
大家一种公认为Quartz是“基于”PDF实现的,这么说也是有一些道理的。PDF(Adobe’s protable Document Format)是一个PostScript绘画模型实现的,它遵循严格的编码规则。Quartz也实现了一套和PDF所兼容的的APIs。
Quartz保留了基本的实现机制,甚至是DPS中的事件处理也被Quartz包含进来了,但是DPS的实现已经完全被Quzrtz所替代,下图可以看到进程栈里出现了DPS的字样:
下一章会对Quartz有更加深入的讲解。我们平时所提到的“图像”,实际在计算机中被抽象成“渲染”,“渲染”可以将图像显示在NSView对象中,或者在UIImage中显示,甚至可以通过PDF来显示。
所有通过CG来绘画的都叫做“context”,context是一个集合,它将所有的数据结构和函数收集起来,然后控制它们如何进行渲染。
有许多不同种类的context,例如NSWindowGraphicsContext(Mac)。这个context将渲染图像的代码放到内存中的一个共享区域中,window server从这个共享区域取出代码,然后显示在屏幕上。
另一个CG context是image context。编写的代码是通过一个个的像素表现,然后这些像素在组成位图。你可以将这个位图context嵌入到其他的context中,或者保存为PNG,JPEG格式。这里还有一种叫PDF的context,这种context的绘画编码不是变成一个个的像素,而是转换程PDF脚本保存成文件。当PDF阅读器打开这个文件的时候,可以将这些脚本进行解析,渲染,转变成我们可以阅读的样式。