Cairo 后端
最后修改于 2023 年 7 月 17 日
Cairo 库支持多种后端。在本节的 Cairo 图形教程中,我们将使用 Cairo 创建 PNG 图像、PDF 文件、SVG 文件,并在 GTK 窗口上绘图。
PNG 图像
在第一个示例中,我们创建了一个 PNG 图像。
#include <cairo.h> int main(void) { cairo_surface_t *surface; cairo_t *cr; surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60); cr = cairo_create(surface); cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 40.0); cairo_move_to(cr, 10.0, 50.0); cairo_show_text(cr, "Disziplin ist Macht."); cairo_surface_write_to_png(surface, "image.png"); cairo_destroy(cr); cairo_surface_destroy(surface); return 0; }
这个示例是一个小的控制台应用程序,它将创建一个 PNG 图像。
#include <cairo.h>
在此头文件中,我们可以找到函数和常量的声明。
cairo_surface_t *surface; cairo_t *cr;
在这里,我们声明了一个表面和一个 Cairo 上下文。
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60); cr = cairo_create(surface);
我们创建了一个表面和一个 Cairo 上下文。该表面是一个 390x60 像素的图像。
cairo_set_source_rgb(cr, 0, 0, 0);
我们使用黑色墨水进行绘制。
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 40.0);
我们选择了一种字体类型并设置了它的尺寸。
cairo_move_to(cr, 10.0, 50.0); cairo_show_text(cr, "Disziplin ist Macht.");
我们将位置移动到图像内的 (10.0, 50.0) 位置并绘制文本。
cairo_surface_write_to_png(surface, "image.png");
此函数调用将创建 PNG 图像。
cairo_destroy(cr); cairo_surface_destroy(surface);
最后,我们清理资源。
PDF 文件
在第二个示例中,我们使用 Cairo 库创建了一个简单的 PDF 文件。
#include <cairo.h> #include <cairo-pdf.h> int main(void) { cairo_surface_t *surface; cairo_t *cr; surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648); cr = cairo_create(surface); cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, 40.0); cairo_move_to(cr, 10.0, 50.0); cairo_show_text(cr, "Disziplin ist Macht."); cairo_show_page(cr); cairo_surface_destroy(surface); cairo_destroy(cr); return 0; }
我们必须在 PDF 查看器中打开 PDF 文件。Linux 用户可以使用 KPDF 或 Evince 查看器。
surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
要渲染 PDF 文件,我们必须使用 `cairo_pdf_surface_create` 函数调用创建一个 PDF 表面。PDF 文件的大小以点为单位指定,这是排版中的标准。
cairo_show_page(cr);
`cairo_show_page` 函数调用完成了 PDF 文件的渲染。

SVG 文件
下一个示例创建了一个简单的 SVG(可缩放矢量图形)文件。SVG 是当今最热门的技术之一。
#include <cairo.h> #include <cairo-svg.h> int main(void) { cairo_surface_t *surface; cairo_t *cr; surface = cairo_svg_surface_create("svgfile.svg", 390, 60); cr = cairo_create(surface); cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 40.0); cairo_move_to(cr, 10.0, 50.0); cairo_show_text(cr, "Disziplin ist Macht."); cairo_surface_destroy(surface); cairo_destroy(cr); return 0; }
我们可以使用 Firefox、Opera 或 Inkscape 程序打开 svgfile.svg 文件。
surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
要在 Cairo 中创建 SVG 文件,我们必须使用 `cairo_svg_surface_create` 函数调用创建一个 SVG 表面。
cr = cairo_create(surface);
Cairo 上下文是从 SVG 表面创建的。
其余代码与前面的示例相同。

GTK 窗口
在最后一个示例中,我们在 GTK 窗口上进行绘制。该后端将用于教程的其余部分。
#include <cairo.h> #include <gtk/gtk.h> static void do_drawing(cairo_t *); static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { do_drawing(cr); return FALSE; } static void do_drawing(cairo_t *cr) { cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 40.0); cairo_move_to(cr, 10.0, 50.0); cairo_show_text(cr, "Disziplin ist Macht."); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *darea; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(window), darea); g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 400, 90); gtk_window_set_title(GTK_WINDOW(window), "GTK window"); gtk_widget_show_all(window); gtk_main(); return 0; }
该示例弹出一个居中的 GTK 窗口,我们在其中绘制“Disziplin ist Macht”文本。
#include <cairo.h> #include <gtk/gtk.h>
我们包含必要的 Cairo 和 GTK 头文件。
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { do_drawing(cr); return FALSE; }
我们将实际绘图委托给 `do_drawing` 函数。传递的参数是 Cairo 上下文。
static void do_drawing(cairo_t *cr) { cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 40.0); cairo_move_to(cr, 10.0, 50.0); cairo_show_text(cr, "Disziplin ist Macht."); }
Cairo 函数执行绘图操作。
darea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(window), darea);
我们创建了一个 `GtkDrawingArea` 小部件并将其添加到容器窗口中。它用于自定义绘图。
g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL);
当 `GtkDrawingArea` 小部件需要重绘时,它会发出 `draw` 信号。我们将该信号连接到 `on_draw_event` 回调。

在本章中,我们介绍了支持的 Cairo 后端。