使用一个非常简单的 API 将坐标转换为路径。这个 API 非常有意义,因为它使我们不必考虑线性代数或图形学课本中讨论的复杂的转换矩阵。可以对 cairo 绘图操作执行任何转换,包括对图形或部分图形进行剪切、缩放或旋转。通过指定点来绘制每条路径。cairo 按照将点连接起来的方法执行操作。在后面将提供一个示例。
接下来,讨论各种 cairo 外表类型。有几种 cairo 外表类型,它们分别对应一种输出目标。cairo 外表(surface)是执行绘图的位置。具体地说,有用于图像(内存缓冲区)的外表、用于 Open GL 的 glitz 外表、用于呈现文档的 PDF 和 PostScript 外表以及用于直接执行绘图的 XLib 和 Win32 外表。这些外表类型都派生自外表基类型 cairo_surface_t。
cairo 的版本号采用与 Linux 内核相似的规则 —— 也就是,奇数版本是实验性的开发版本,不适合在生产环境中使用。偶数版本是稳定版本:最初的 1.0 版本主要关注顺利地向用户提供 API 和产生高质量输出。1.2 API 完善了几个开发不太完整的后端,当前的 1.4 系列主要关注优化和添加新功能。
cairo 的开发人员提供了一些出色的示例代码片段,演示了 cairo API 的各种功能(见 参考资料 一节中的链接)。所以不必等待 cairo 的下一个版本了,现在就下载并试用当前版本!
阅读 GNOME Journal 文章 “Writing a Widget Using Cairo and GTK+2.8”。
Technical Advisory Service for Images(TASI)提供了 常用矢量图形术语及解释。
关于作者
Eli Dow 是位于 Poughkeepsie, NY. 的 IBM Linux Test and Integration Center 的一名软件工程师。他拥有 Clarkson 大学的计算机科学和心理学学士学位,以及计算机科学硕士学位。他的兴趣包括 GNOME 桌面、人与计算机的交互以及 Linux 系统编程。您可以通过 emdow@us.ibm.com 与 Eli 联系。
/* This path desribes what will be drawn later The bulk of it is doing the IBM letters by connect the dots at the very end, we will get fancy and add a (R) Registered logo. */ static void travel_path (cairo_t *cr) { gint pen_radius = 10;
/* We stroke the path so we see everything we just specified by connecting the dots */ cairo_stroke(cr);
/* Let us add a disclaimer and show some fancy cairo: */ /* We are going to want a nice fine lined circle around the R you need to make sure you have stroked existing things that you wanted drawn with the larger pen before continuing. */ cairo_set_line_width (cr, pen_radius*.5);
/* Now we will draw the fancy circle around the "R" */ /* NOTE: The angles are in radians */ cairo_move_to (cr, 710, 200); double angle1 = 0 * (M_PI/180.0); double angle2 = 360 * (M_PI/180.0);
/* We draw a large black circle */ cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_arc (cr, 710, 200, 20, angle1, angle2); cairo_stroke (cr);
/* We draw a smaller white circle centered on it */ cairo_set_source_rgba (cr, 1, 1, 1, 1); cairo_arc (cr, 710, 200, 20, angle1, angle2); /* We use the fill operator to fill in the circle! */ cairo_fill (cr);
/* We are going to draw the letter "R" with black pen*/
cairo_move_to (cr, 695,212); /* Bottom left of text at point */ cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 40); cairo_show_text (cr, "R");
/* We stroke everything we have just done to actually draw it... */ cairo_stroke (cr);
/* Try applying the scale and rotate factors here to examine their effects on the output!*/ /* cairo_rotate (cr, -M_PI / 4); */ /* cairo_scale (cr, 2, 1.0); */
travel_path (cr); cairo_destroy (cr); }
/* Function needed to draw to gtk window */ static void draw_gtk (GtkWidget *widget, GdkEventExpose *eev, gpointer data) { cairo_t *cr; cr = gdk_cairo_create (widget->window); travel_path (cr); cairo_destroy (cr); }
/* We will draw our path on multiple surfaces to demonstrate some of the various cairo backend */ int main (gint argc, gchar **argv) { cairo_surface_t *surface;
/* GTK Window using Cairo */ gtk_init (NULL, NULL); /* Fire up GTK! */ GtkWidget *mainwin; /* Make a new windows */ GtkWidget *canvas = NULL; /* Make a new canvas */
/* Instead of drawing like usual, we connect the expose event to do the drawing! */ g_signal_connect (G_OBJECT (canvas), "expose-event", G_CALLBACK (draw_gtk), NULL);
gtk_widget_show_all (mainwin); /* Show the window on the screen */ gtk_main (); return 0; }