1. 简介
Linux的两大流行桌面环境KDE和Gnome,其对应的基础组件QT和GTK+,GTK+的底层图形绘制用的就是cairo。cairo (http://cairographics.org)是开源矢量图形库支持多种输出,cairo由c语言编写模块化设计得很出色,这里分享(非教程)cairo的windows移植定制(VS2012编译),及跟windows的图形接口DXGI对接,通过DXGI来渲染显示cairo产生的图像帧。
2. cairo 图形库
cairo是个不小的工程,多少行就没去统计,cairo-1.12.18源码包65.9M,去除测试文件、测试代码、文档、其源代码文件近10M。移植当然是从readme入手,文档说用Cygwin或MSYS编译,自己用VS当然也可以。
- 在cairo/src创建cairo-features.h,描述cairo的功能模块。这个算是大幅定制版本,IMAGE、FT(FreeType)是必须,PNG方便用来查看图像,SVG、PDF是广泛使用的矢量图形格式,XML、RECORDING是我临时用配上的
- 创建cairo的VS Win32 DLL空项目,src\Makefile.sources里有代码文件列表,代码的组织结构,按照这个文件结合配置的模块添加代码。另外,还有一些依赖库pixman、zlib、libpng、freetype,其中libpng也都依赖zlib。这些库都可以用最新版本,创建VS项目都差不多主要是看官方文档说明
- 编译生成DLL,编译cairo有一千多条警告,最后生成的DLL文件Debug版2.9M,Release版1.3M。其他依赖库当然要提前编译好,zlib是编译为DLL,pixman、libpng、freetype均使用静态库。编译好DLL后就可以使用cairo绘图了,绘制的图像在一个可以访问的内存里
3. Windows 图形接口
上面两张图摘自微软官方文档,左边是windows xp图形系统接口,右边是vista及其之后windows的。从vista开始,微软设计了全新的显示驱动模型,调整了图形系统架构,可以提供更好的图像质量,可以为界面提供硬件加速。参考文档:https://msdn.microsoft.com/en-us/library/ee417756(v=vs.85).aspx
上图是DXGI(DirectX Graphics Infrastructure),是从vista开始的一个新的子系统。DXGI用于处理一些底层任务如枚举硬件设备,创建缓存交互链(swap-chain),呈现渲染好的图像帧到输出设备等,程序可以直接访问DXGI。参考文档:https://msdn.microsoft.com/en-us/library/bb205075(v=vs.85).aspx
4. 显示cairo的图像帧
显示内存中的一幅图像方法可以通过GDI,也可以走D3D/OPENGL纹理,但是将图像数据写到显示帧缓冲无疑是快速的方式。我编写了一个程序,用于将内存中的图像数据写到buffer。阅读官方的Programming Guide还有Reference,文档位于(MSDN章节)Desktop app technologies-----> Graphics and Gaming-----> Direct 2D / Direct 3D / DirectX Graphics Articles
cairo创建surface其像素格式CAIRO_FORMAT_RGB24是32位,对于的buffer像素格式DXGI_FORMAT_B8G8R8A8_UNORM。desc.OutputWindow即是关联的输出窗口。cairo绘图完毕后调用cairo_image_surface_get_data 得到图像数据,我简单的封装了一个函数将数据写入buffer。
下面是绘图代码和产生的图像
5. 结束语
有 .NET,有基于Web UI的hybrid APP框架,有类似于QT的整套解决方案,估计很少人会使用专业的图形库去创建UI界面。这个库可以用在一些高效绘图的场合,像windows 8任务管理器的性能界面。都说下一代的人机交互是语音甚至视觉,当用户对着机器说话,或是通过机器视觉(OpenCV)分析出用户的输入,到时候UI会不会变得非常简单高效,像钢铁侠、遗落战境、等等科幻大片一样,没有button、scrollbar,不需要touch,要的只是快速的绘制与呈现,及时的将信息传达给用户,相信这是人机交互的发展趋势。