Cairo是一个2D图形库,支持多种输出设备。
支持的输出目标包括X Window,Quartz,Win32,image.buffers,PostScript,PDF和SVG文件输出。
后续支持OpenGL,XCB,BeOS,OS/2操作系统和DirectFB。
Cairo的目的是同一输出在不同的输出媒体上,同时能利用硬件加速器。
主要优点:在X、Win32、Quartz的基础上统一了图形库的操作方式,同时支持PS、PDF、SVG、PNG/JPEG等图像格式的输出,方便页面的再次利用,在glitz的支持下支持部分3D效果。
gtk使用cairo在窗口或者控件上绘图,需要注意以下几点:
绘图目标是GdkDrawable,Drawable,顾名思义,是支持在其上绘图的东西,是GdkWindow或GdkPixmap 对象。对于gtk控件,它们是结构体,一般是它的window属性
使用gtk_widget_set_app_paintable()方法将控件设置为可绘图
绘图过程写在"expose-event"事件的回调函数中
如果窗口里有其它控件,回调函数必须返回FALSE,否则窗口里的控件会被绘图覆盖
控件必须得到显示才能被绘制,否则会在运行时报错IA__gdk_cairo_create:gdk_cairo_create: assertion `GDK_IS_DRAWABLE (drawable)' failed
源代码:
#include <gtk/gtk.h>
#include <cairo.h>
static gboolean on_expose_event (GtkWidget * widget, GdkEventExpose * event, gpointer data)
{
cairo_t *cr;
cr = gdk_cairo_create (widget->window);
//设置画笔颜色和线段粗细
cairo_set_source_rgb(cr,0,0,0);
cairo_set_line_width(cr,5);
//画直线,用 cairo_move_to() 和 cairo_line_to() 函数在 cr 中定义绘图路径 (path)
cairo_move_to(cr,10, 34);
cairo_line_to(cr,111,111);
//cairo_stroke() 函数会将 cr 中的路径绘制出来
cairo_stroke(cr);
//设置画笔颜色和字体大小
cairo_set_source_rgb(cr,30000,0,50000);
cairo_set_font_size (cr, 24.0);
cairo_move_to (cr, 100, 55);
//写字
cairo_show_text (cr, "223232323232323");
cairo_destroy (cr);
return FALSE;
}
int main(int argc,char* argv[]){
GtkWidget* window;
gtk_init(&argc,&argv);
//创建新窗口
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"drawDemo");
gtk_window_set_default_size(GTK_WINDOW(window),300,200);
//关联窗口关闭回调函数
g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
//关联窗口重绘事件的回调函数
g_signal_connect (window, "expose-event", G_CALLBACK (on_expose_event), NULL);
//设置窗口可绘制
gtk_widget_set_app_paintable(window,TRUE);
//显示窗口
gtk_widget_show_all(window);
gtk_main();
return 0;
}
效果:

使用cairo库实现绘制窗体背景图:
把函数修改,并且关联gtk window的"expose-event"回调函数就行了
gboolean on_expose_event (GtkWidget * widget, GdkEventExpose * event, gpointer data)
{
cairo_t *cr;
cr = gdk_cairo_create (widget->window);
// 加载图片
GdkPixbuf *image = gdk_pixbuf_new_from_file("imgs/bg0.jpg", NULL);
if (!image) {
g_print("Failed to load image\n");
return FALSE;
}
// 缩放的图片大小(实际窗体大小)
gint width;
gint height;
gtk_window_get_size(GTK_WINDOW(widget),&width,&height);
// 缩放图片
GdkPixbuf *scaled_image = gdk_pixbuf_scale_simple(image, width, height, GDK_INTERP_BILINEAR);
g_object_unref(image);
// 在控件上绘制图片 后面两个参数是起始位置
gdk_cairo_set_source_pixbuf(cr, scaled_image, 0, 0);
cairo_paint(cr);
// 释放资源
g_object_unref(scaled_image);
cairo_destroy (cr);
return FALSE;
}