pfan123/Articles

Cairo 二维矢量图形库

pfan123 opened this issue · 0 comments

二维矢量图形

计算机图形可分为两类,矢量图形与光栅图形。光栅图形是将图像表示为像素点集。矢量图形则是使用一些几何图元(点、直线、曲线、多边形等)表示图像,这些图元是使用数学公式生成的。

Cairo

Cairo 是用于绘制二维矢量图形的库,采用 C 语言实现,又被许多其它计算机语言所绑定,譬如 Python、PERL、C++、C#、Java。Cairo 是跨平台库,可运行于 Linux、BSD、OSX 等操作系统。

Cairo 力求在各种后端上产生相同的输出,但是每种后端各有优势。例如,PDF 后端会尽可能使用矢量计算(只在必要时生成图像),而 PostScript 后端实际上会为每个页面生成一个大图像。

Cairo 的呈现模型受到许多原有技术的影响。Cairo 采用了 PostScript 中的路径、笔画(stroke)和填充(fill)概念,还实现了 PDF 和现代 X 服务器实现的呈现扩展中的 Porter-Duff 图像组合技术。另外,cairo 还实现了剪切、蒙板和渐变等补充特性。

Cairo 支持多种后端 (backend):

  • X Window 系统
  • Win32 GDI
  • Mac OS X Quartz
  • PNG
  • PDF
  • PostScript(Encapsulated PostScript)
  • SVG

这些后端意味着可使用 Cairo 库在 Windows、Linux/BSD、OSX 等平台的窗口中绘图,也可以用于生成 PNG 图片、PDF/PostScript/SVG 文件。

与 Windows 操作系统的 GDI+ 以及 Mac OS 的 Quartz 2D 库相比,Cairo 是自由软件库。自 GTK+ 2.8 版本开始,Cairo 成为 GTK+ 库的一部分。

Cairo 基本绘图模块

Cairo API 分为三大模块:核心绘图类(Drawing)、外表类(Surfaces)和与字体(Fonts)相关的类(更多细节见 参考资料)。

核心绘图类(Drawing)

Cairo 有一个绘图上下文(drawing context),相当于画布。上下文是 Context 是 Cairo 的核心结构,在 Cairo 中使用 cairo_t 来表示,呈现图形。在绘图上下文上通过 Paths,绘制可以绘制一系列曲线和相关数据的路径,还可设置笔画宽度或填充。Cairo 笔画路径含有 5 种基本绘图操作:

  cairo_stroke
  cairo_fill
  cairo_show_text/cairo_show_glyphs
  cairo_paint
  cairo_mask

Cairo 还提供类似 OpenGL 的坐标变换操作。变换操作包括:平移 cairo_translate ,伸缩 cairo_scale,旋转 cairo_rotate。我们也可以通过 cairo_transform 函数来指定一个复杂的变换。

外表类(Surfaces)

Cairo 外表类型,对应各种输出目标。Cairo 外表(surface)是执行绘图的位置。具体地说,有用于图像(内存缓冲区)的外表、用于 Open GL 的 glitz 外表、用于呈现文档的 PDF 和 PostScript 外表以及用于直接执行绘图的 XLib 和 Win32 外表。这些外表类型都派生自外表基类型 cairo_surface_t

字体(Fonts)

Cairo 为字体提供了一个基类 cairo_font_face_t。Cairo 支持可缩放字体,其中包含给定字体大小的缓存标准。另外,可以用各种字体选项控制如何显示给定的字体。在使用 Cairo 时,在 UNIX 上常用的字体是 Freetype 字体,在 Windows 平台上使用 Win32 字体。

绘制一个矩形到 rectangle.png 图片上,示例:

#include <cairo.h>
#include <png.h>

int
main (int argc, char *argv[])
{
    cairo_surface_t *surface;
    cairo_t *cr;
 
    int width = 640;
    int height = 480;
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
 
    /* Drawing code goes here */
    cairo_set_line_width (cr, 10);
    cairo_set_source_rgb (cr, 0, 0, 0);
    cairo_rectangle (cr, width/4, height/4, width/2, height/2);
    cairo_stroke (cr);
 
    /* Write output and clean up */
    cairo_surface_write_to_png (surface, "./rectangle.png");
    cairo_destroy (cr);
    cairo_surface_destroy (surface);
 
    return 0;
}

Mac 环境下编译安装 Cairo

1.安装

  • 使用 MacPorts 安装
  sudo port install cairo
  • 使用 fink 安装
 sudo apt-get install cairo
  • 使用 Homebrew 安装
 brew install cairo

2.设置环境变量

安装完 cairo, 需设置环境变量:

For compilers to find libffi you may need to set:
  export LDFLAGS="-L/usr/local/opt/libffi/lib"

For pkg-config to find libffi you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig"

3.安装 gcc 编译器

由于 cairo 采用 C 语言实现,mac环境需使用 gcc 编译

 brew install gcc

gcc 编译,可以把前面讲的例子命名为 cairotest.c 文件进行编译,会生成 rectangle.png 文件

gcc -o cairotest $(pkg-config --cflags --libs cairo) cairotest.c
或
gcc -o cairotest `pkg-config --cflags --libs cairo` cairotest.c

小知识: .cpp和.c 文件区别

.cpp是c++的源文件, c++语言兼容c语言, 编写c语言代码可以用c++的源文件.cpp
.c是纯粹的c语言文件, 不可以有c++语言的代码, 默认自带一些库文件
c++语言兼容c语言, c语言是面向过程, c++语言既能面向过程也可以面向对象

Cairo 实际应用

许多有影响力的开放源码项目已经采用了 Cairo,Cairo 已经成为 Linux 图形领域的重要软件。已经采用 Cairo 的重要项目包括:

  • node-canvas,Web Canvas API的一个实现,并尽可能地实现该API
  • CairoSVG,是SVG 1.1到PNG,PDF,PS和SVG转换器。j
  • librsvg,SVG渲染库
  • Gtk+,一个广受喜爱的跨平台图形工具集
  • Pango,一个用于布置和呈现文本的免费软件库,它主要用于实现国际化
  • Gnome,一个免费的桌面环境
  • Mozilla,一个跨平台的 Web 浏览器基础结构,Firefox 就是在这个基础结构上构建的
  • OpenOffice.org,一个可以与 Microsoft Office 匹敌的免费办公套件

参考资料:
Cairo
cairo repository
Cairo 图形指南
cairo-demo
CairoSVG
Ghostscript
postscript
Encapsulated PostScript (EPS) File Format, Version 3.x
Encapsulated PostScript
C语言中.h和.c文件解析
C++/C/JAVA/Python之间的区别?