原文: https://zetcode.com/gfx/cairo/cairobackends/

Cairo 库支持各种后端。 在 Cairo 图形教程的这一部分中,我们将使用 Cairo 创建 PNG 图像,PDF 文件,SVG 文件,并在 GTK 窗口上绘制。

PNG 图像

在第一个示例中,我们将创建一个 PNG 图像。

  1. #include <cairo.h>
  2. int main(void)
  3. {
  4. cairo_surface_t *surface;
  5. cairo_t *cr;
  6. surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
  7. cr = cairo_create(surface);
  8. cairo_set_source_rgb(cr, 0, 0, 0);
  9. cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
  10. CAIRO_FONT_WEIGHT_NORMAL);
  11. cairo_set_font_size(cr, 40.0);
  12. cairo_move_to(cr, 10.0, 50.0);
  13. cairo_show_text(cr, "Disziplin ist Macht.");
  14. cairo_surface_write_to_png(surface, "image.png");
  15. cairo_destroy(cr);
  16. cairo_surface_destroy(surface);
  17. return 0;
  18. }

本示例是一个小型控制台应用,它将创建一个 PNG 图像。

  1. #include <cairo.h>

在此头文件中,我们将找到函数和常量的声明。

  1. cairo_surface_t *surface;
  2. cairo_t *cr;

在这里,我们声明一个表面和一个 Cairo 上下文。

  1. surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
  2. cr = cairo_create(surface);

我们创建一个表面和一个 Cairo 上下文。 表面是 390x60 像素的图像。

  1. cairo_set_source_rgb(cr, 0, 0, 0);

我们将用黑色墨水绘制。

  1. cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
  2. CAIRO_FONT_WEIGHT_NORMAL);
  3. cairo_set_font_size(cr, 40.0);

我们选择一种字体类型并设置其大小。

  1. cairo_move_to(cr, 10.0, 50.0);
  2. cairo_show_text(cr, "Disziplin ist Macht.");

我们移到图像内的(10.0,50.0)位置并绘制文本。

  1. cairo_surface_write_to_png(surface, "image.png");

此函数调用将创建 PNG 图像。

  1. cairo_destroy(cr);
  2. cairo_surface_destroy(surface);

最后,我们清理资源。

PDF 文件

在第二个示例中,我们将使用 Cairo 库创建一个简单的 PDF 文件。

  1. #include <cairo.h>
  2. #include <cairo-pdf.h>
  3. int main(void)
  4. {
  5. cairo_surface_t *surface;
  6. cairo_t *cr;
  7. surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
  8. cr = cairo_create(surface);
  9. cairo_set_source_rgb(cr, 0, 0, 0);
  10. cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
  11. CAIRO_FONT_WEIGHT_NORMAL);
  12. cairo_set_font_size (cr, 40.0);
  13. cairo_move_to(cr, 10.0, 50.0);
  14. cairo_show_text(cr, "Disziplin ist Macht.");
  15. cairo_show_page(cr);
  16. cairo_surface_destroy(surface);
  17. cairo_destroy(cr);
  18. return 0;
  19. }

我们必须在 PDF 查看器中打开 PDF 文件。 Linux 用户可以使用 KPDF 或 Evince 查看器。

  1. surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);

要渲染 PDF 文件,我们必须使用cairo_pdf_surface_create()函数调用来创建 PDF 曲面。 PDF 文件的大小以磅为单位指定,这是排版的标准。

  1. cairo_show_page(cr);

cairo_show_page()完成 PDF 文件的渲染。

Cairo 后端 - 图1

图:Evince 中的 PDF 文件

SVG 文件

下一个示例创建一个简单的 SVG(可缩放矢量图形)文件。 SVG 是当今最热门的技术之一。

  1. #include <cairo.h>
  2. #include <cairo-svg.h>
  3. int main(void)
  4. {
  5. cairo_surface_t *surface;
  6. cairo_t *cr;
  7. surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
  8. cr = cairo_create(surface);
  9. cairo_set_source_rgb(cr, 0, 0, 0);
  10. cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
  11. CAIRO_FONT_WEIGHT_NORMAL);
  12. cairo_set_font_size(cr, 40.0);
  13. cairo_move_to(cr, 10.0, 50.0);
  14. cairo_show_text(cr, "Disziplin ist Macht.");
  15. cairo_surface_destroy(surface);
  16. cairo_destroy(cr);
  17. return 0;
  18. }

我们可以使用 Firefox,Opera 或 Inkscape 程序打开svgfile.svg文件。

  1. surface = cairo_svg_surface_create("svgfile.svg", 390, 60);

要在 Cairo 创建 SVG 文件,我们必须使用cairo_svg_surface_create()函数调用来创建 svg 曲面。

  1. cr = cairo_create(surface);

Cairo 上下文是从 SVG 曲面创建的。

其余代码与前面的示例相同。

Cairo 后端 - 图2

SVG file in Chrome

GTK 窗口

在最后一个示例中,我们将在 GTK 窗口上绘制。 该后端将在本教程的其余部分中使用。

  1. #include <cairo.h>
  2. #include <gtk/gtk.h>
  3. static void do_drawing(cairo_t *);
  4. static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
  5. gpointer user_data)
  6. {
  7. do_drawing(cr);
  8. return FALSE;
  9. }
  10. static void do_drawing(cairo_t *cr)
  11. {
  12. cairo_set_source_rgb(cr, 0, 0, 0);
  13. cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
  14. CAIRO_FONT_WEIGHT_NORMAL);
  15. cairo_set_font_size(cr, 40.0);
  16. cairo_move_to(cr, 10.0, 50.0);
  17. cairo_show_text(cr, "Disziplin ist Macht.");
  18. }
  19. int main(int argc, char *argv[])
  20. {
  21. GtkWidget *window;
  22. GtkWidget *darea;
  23. gtk_init(&argc, &argv);
  24. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  25. darea = gtk_drawing_area_new();
  26. gtk_container_add(GTK_CONTAINER(window), darea);
  27. g_signal_connect(G_OBJECT(darea), "draw",
  28. G_CALLBACK(on_draw_event), NULL);
  29. g_signal_connect(window, "destroy",
  30. G_CALLBACK(gtk_main_quit), NULL);
  31. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  32. gtk_window_set_default_size(GTK_WINDOW(window), 400, 90);
  33. gtk_window_set_title(GTK_WINDOW(window), "GTK window");
  34. gtk_widget_show_all(window);
  35. gtk_main();
  36. return 0;
  37. }

该示例弹出一个居中的 GTK 窗口,在该窗口上绘制"Disziplin ist Macht"文本。

  1. #include <cairo.h>
  2. #include <gtk/gtk.h>

我们包括必要的 Cairo 和 GTK 标头。

  1. static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
  2. gpointer user_data)
  3. {
  4. do_drawing(cr);
  5. return FALSE;
  6. }

我们将实际图形委托给do_drawing()函数。 发送的参数是 Cairo 上下文。

  1. static void do_drawing(cairo_t *cr)
  2. {
  3. cairo_set_source_rgb(cr, 0, 0, 0);
  4. cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
  5. CAIRO_FONT_WEIGHT_NORMAL);
  6. cairo_set_font_size(cr, 40.0);
  7. cairo_move_to(cr, 10.0, 50.0);
  8. cairo_show_text(cr, "Disziplin ist Macht.");
  9. }

Cairo 功能执行绘图。

  1. darea = gtk_drawing_area_new();
  2. gtk_container_add(GTK_CONTAINER(window), darea);

我们创建一个GtkDrawingArea小部件,并将其添加到容器窗口。 用于自定义绘图。

  1. g_signal_connect(G_OBJECT(darea), "draw",
  2. G_CALLBACK(on_draw_event), NULL);

当需要重新绘制GtkDrawingArea小部件时,它将发出draw信号。 我们将该信号连接到on_draw_event()回调。

Cairo 后端 - 图3

图:GTK 窗口

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