• Cairo编程


    一、简介

    cairo 是一个免费的矢量绘图软件库,它可以绘制多种输出格式。cairo 支持许多平台,包括 Linux、BSD、Microsoft® Windows® 和 OSX(BeOS 和 OS2 后端也正在开发)。Linux 绘图可以通过 X Window 系统、Quartz、图像缓冲格式或 OpenGL 上下文来实现。另外,cairo 还支持生成 PostScript 或 PDF 输出,从而产生高质量的打印结果。在理想情况下,cairo 的用户可以在打印机和屏幕上获得非常接近的输出效果。

    专业术语

     

    1、环境 (Context)
    使用 Cairo 绘图,必须要首先创建 Cairo 环境 (Context)。Cairo 环境保存着所有的图形状态参数,这些参数描述了图形的构成,譬如线条宽度、颜色、要绘制的外观 (Surface) 以及其它一些信息。Cairo 环境允许真正的绘图函数使用很少的一部分参数,以此提高接口的易用性。调用 gdk_cairo_create () 函数可为所绘制的图形创建一个 Cairo 环境。

    cairo_t * cr;
    cr = gdk_cairo_create (widget->window);

    这两行代码创建了一个 Cairo 环境,并且这个 Cairo 环境是关联到 GdkDrawable 对象上的。cairo_t 结构体包含了当前渲染设备的状态,也包含了所绘制图形的坐标。从技术上来讲,cairo_t 就是所谓的 Cairo 环境。

    Cairo 所有的绘图函数都要去操作 cairo_t 对象。一个 Cairo 环境可以被关联到一种特定的外观,譬如 pdf、svg、png、GdkDrawable 等。

    GDK 没有对 Cairo API 进行封装,它只允许创建一个可基于 GdkDrawable 对象绘制图形的 Cairo 环境。有一些 GDK 函数可以将 GDK 的矩形或填充区域转换为 Cairo Path (路径),然后使用 Cairo 绘图与渲染。

    2、路径 (Path)
    一条 Path(路径)通常是由一条或多条首尾相接的直线段构成的,也可以由直线段与曲线段构成。路径可分为 Open(开放)类型与 Closed(闭合)类型,前者的首尾端点不重合,后者的首尾端点重合。

    在 Cairo 中,绘图要从一条空路径开始,首先定义一条路径,然后通过绘制/填充操作使之可见。要注意的是,每次调用 cairo_stroke () 或 cairo_fill () 函数之后,路径会被清空,不得不再定义新的路径。
    一条路径可由一些子路径构成。

    3、源 (Source)
    源好比绘图中所使用的画笔/颜料,使用它来绘制/填充图形轮廓。有 4 种基本的源:color、gradient、pattern 与 image。

    4、外观 (Surface)
    Surface 就是要绘制图形的最终体现形式,譬如可使用 PDF 或 PostScript 外观实现文本内容的渲染,或者使用 Xlib、Win32 外观实现屏幕绘图。
    Cairo 具体有那些外观类型,可参考其定义:

    typedef enum _cairo_surface_type {
      CAIRO_SURFACE_TYPE_IMAGE,
      CAIRO_SURFACE_TYPE_PDF,
      CAIRO_SURFACE_TYPE_PS,
      CAIRO_SURFACE_TYPE_XLIB,
      CAIRO_SURFACE_TYPE_XCB,
      CAIRO_SURFACE_TYPE_GLITZ,
      CAIRO_SURFACE_TYPE_QUARTZ,
      CAIRO_SURFACE_TYPE_WIN32,
      CAIRO_SURFACE_TYPE_BEOS,
      CAIRO_SURFACE_TYPE_DIRECTFB,
      CAIRO_SURFACE_TYPE_SVG,
      CAIRO_SURFACE_TYPE_OS2
    } cairo_surface_type_t;

    5、蒙板 (Mask)
    在源作用于外观之前,可对其实现过滤,蒙板 (mask) 即是过滤器。蒙板决定哪些源可被显示。蒙板不透明的部分允许复制源至外观,蒙板透明的部分则禁止复制源至外观。、

    6、图案 (Pattern)
    图案表示被绘制到外观的源。在 Cairo 中,图案是一种可以读取的内容,可用作绘图操作的源或蒙板。图案可以是纯色模式、基于外观的模式以及渐变模式。

     

     

    二、编译与安装

    参考:http://cairographics.org/download/

    执行以下命令,即可完成安装

    sudo yum install cairo-devel
    如下图

    image

    三、编程

    程序1:用于生成 PNG 图像

    #include <cairo.h>
    
    int main (int argc, char *argv[])
    {
            cairo_surface_t *surface;
            cairo_t *cr;
    
            surface =cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 400, 800);
            cr = cairo_create (surface);
    
            cairo_set_source_rgb (cr, 1, 0, 0);
            cairo_rectangle(cr,0,0,400,800);
            cairo_fill(cr);
             cairo_select_font_face (cr, "Adobe Heiti Std", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
            cairo_set_font_size (cr, 30.0);
    
            cairo_move_to (cr, 100, 400);
            cairo_set_source_rgb (cr, 0, 1, 0);
            cairo_show_text (cr, "I Love Chinese !");
    
            cairo_surface_write_to_png (surface, "image.png");
    
            cairo_destroy (cr);
            cairo_surface_destroy (surface);
    
            return 0;
    }

    编译

    gcc -o example-1.o example-1.c -lcairo -I/usr/include/cairo

    运行

    image

    程序2:用于生成 PDF 图像

    #include <cairo.h>
    #include <cairo-pdf.h>
    
    int main (int argc, char *argv[])
    {
            cairo_surface_t *surface;
            cairo_t *cr;
    
            surface = cairo_pdf_surface_create ("pdffile.pdf", 20, 40);
            cr = cairo_create (surface);
    
            cairo_set_source_rgb (cr, 1, 0, 0);
            cairo_rectangle(cr,0,0,20,40);
            cairo_fill(cr);
             cairo_select_font_face (cr, "WenQuanYi Zen Hei", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
            cairo_set_font_size (cr, 5);
    
            cairo_move_to (cr, 0, 20);
            cairo_set_source_rgb (cr, 0, 1, 0);
            cairo_show_text (cr, "热爱编程");
    
            cairo_show_page (cr);
    
            cairo_destroy (cr);
            cairo_surface_destroy (surface);
    
            return 0;
    }

    编译

    gcc -o example-2.o example-2.c -lcairo -I/usr/include/cairo

    运行

    image

    程序3:用于生成 SVG 图像

    #include <cairo.h>
    #include <cairo-svg.h>
    
    int main (int argc, char *argv[])
    {
            cairo_surface_t *surface;
            cairo_t *cr;
    
            surface = cairo_svg_surface_create ("svgfile.svg", 20, 40);
            cr = cairo_create (surface);
    
            cairo_set_source_rgb (cr, 1, 0, 0);
            cairo_rectangle(cr,0,0,20,40);
            cairo_fill(cr);
             cairo_select_font_face (cr, "WenQuanYi Zen Hei", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
            cairo_set_font_size (cr, 5);
    
            cairo_move_to (cr, 0, 20);
            cairo_set_source_rgb (cr, 0, 1, 0);
            cairo_show_text (cr, "热爱编程");
    
            cairo_destroy (cr);
            cairo_surface_destroy (surface);
    
            return 0;
    }

    编译

    gcc -o example-3.o example-3.c -lcairo -I/usr/include/cairo

    运行

    image

    程序4:在 GTK 窗口中使用 Cairo 绘制图形

    要在 GTK+ 窗口中绘制 Cairo 图形,可以使用 GtkDrawingArea widget 或者更为简单的 GtkWindow widget,本例选择 GtkWindow 。由 GtkWindow widget 对 expose-event 信号处理后,默认要重新绘制窗口背景,这会将我们在 on_expose_event () 函数中定义的 Cairo 图形覆盖掉,因此需要调用 gtk_widget_set_app_paintable () 函数通知 GTK+ 不要这么干。如果是在 GtkDrawingArea widget 中绘制 Cairo 图形,则可省区这一步。

    #include <cairo.h>
    #include <gtk/gtk.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.627, 0, 0);
        cairo_select_font_face (cr, "WenQuanYi Zen Hei", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
        cairo_set_font_size (cr, 24.0);
    
        cairo_move_to (cr, 10.0, 34.0);
        cairo_show_text (cr, "编程艺术");
    
        cairo_destroy (cr);
    
        return FALSE;
    }
    
    
    int main (int argc, char *argv[])
    {
    
        GtkWidget *window;
    
        gtk_init (&argc, &argv);
    
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect (window, "expose-event", G_CALLBACK (on_expose_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), 320, 48);
        gtk_widget_set_app_paintable (window, TRUE);
    
        gtk_widget_show_all (window);
    
        gtk_main ();
    
        return 0;
    }

    编译

    gcc -o example-5.o example-5.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序5:绘制动态图形

    #include <cairo.h>
    #include <gtk/gtk.h>
    #include <math.h>
    
    cairo_surface_t *image;
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
        cairo_t *cr;
    
        static gint pos_x = 128;
        static gint pos_y = 128;
        gint radius = 40;
    
        static gint delta[] = { 3, 3 };
    
        cr = gdk_cairo_create(widget->window);
    
        gint width, height;
        gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
    
        if (pos_x < 0 + radius)
        {
            delta[0] = rand() % 4 + 5;
        }
        else if (pos_x > width - radius)
        {
            delta[0] = -(rand() % 4 + 5);
        }
    
        if (pos_y < 0 + radius)
        {
            delta[1] = rand() % 4 + 5;
        }
        else if (pos_y > height - radius)
        {
            delta[1] = -(rand() % 4 + 5);
        }
    
        pos_x += delta[0];
        pos_y += delta[1];
    
        cairo_set_source_surface(cr, image, 1, 1);
        cairo_arc(cr, pos_x, pos_y, radius, 0, 2*M_PI);
        cairo_clip(cr);
        cairo_paint(cr);
    
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    static gboolean time_handler (GtkWidget *widget)
    {
        if (widget->window == NULL) return FALSE;
        gtk_widget_queue_draw(widget);
        return TRUE;
    }
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
        gint width, height;
    
        image = cairo_image_surface_create_from_png("turnacastle.png");
        width = cairo_image_surface_get_width(image);
        height = cairo_image_surface_get_height(image);
    
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(on_expose_event), NULL);
        g_signal_connect(G_OBJECT(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), width+2, height+2);
    
        gtk_widget_set_app_paintable(window, TRUE);
        gtk_widget_show_all(window);
        g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) window);
    
        gtk_main();
    
        cairo_surface_destroy(image);
    
        return 0;
    }

    编译

    gcc -o example-6.o example-6.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序6:相交区域处理示例

    #include <cairo.h>
    #include <gtk/gtk.h>
    #include <math.h>
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
        cairo_t *cr;
        cr = gdk_cairo_create(widget->window);
    
        static gboolean xdirection = TRUE;
        static gint counter = 0;
    
        int width, height;
        gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
    
        static gdouble rotate = 0;
    
        static gint bigx = 20;
        static gint bigy = 200;
        static gint delta = 1;
    
        counter += 1;
    
    
        if (bigx > width)
        {
            xdirection = FALSE;
            delta = -delta;
            bigx = width;
        }
    
        if (bigx < 1)
        {
            bigx = 1;
            delta = -delta;
        }
    
        if (bigy > height)
        {
            xdirection = TRUE;
            delta = -delta;
            bigy = height;
        }
    
        if (bigy < 1)
        {
            delta = -delta;
            bigy = 1;
        }
    
        if (xdirection)
        {
            bigx += delta;
        }
        else
        {
            bigy += delta;
        }
    
        cairo_translate(cr, width / 2, height /2);
    
        cairo_rectangle(cr, -bigx/2, -bigy/2, bigx-2, bigy-2);
        cairo_set_source_rgb(cr, 0, 0, 0);
        cairo_set_line_width(cr, 1);
        cairo_stroke(cr);
    
        cairo_rotate(cr, rotate);
        rotate += 0.01;
    
        cairo_rectangle(cr, -50, -25, 100, 50);
        cairo_stroke(cr);
    
        GdkRectangle bigrect;
        GdkRectangle rect;
        GdkRectangle intersect;
    
        bigrect.x = -bigx/2;
        bigrect.y = -bigy/2;
        bigrect.width = bigx -2;
        bigrect.height = bigy -2;
    
        rect.x = -50;
        rect.y = -25;
        rect.width = 100;
        rect.height = 50;
    
        gdk_rectangle_intersect(&bigrect, &rect, &intersect);
        cairo_rectangle(cr, intersect.x, intersect.y, intersect.width, intersect.height);
        cairo_fill(cr);
    
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    static gboolean time_handler (GtkWidget *widget)
    {
        if (widget->window == NULL) return FALSE;
        gtk_widget_queue_draw(widget);
        return TRUE;
    }
    
    int main (int argc, char *argv[])
    {
    
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(on_expose_event), NULL);
        g_signal_connect(G_OBJECT(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), 250, 200);
    
        gtk_widget_set_app_paintable(window, TRUE);
        gtk_widget_show_all(window);
        g_timeout_add(5, (GSourceFunc) time_handler, (gpointer) window);
    
        gtk_main();
    
        return 0;
    }

    编译

    gcc -o example-7.o example-7.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序7:遮蔽应用示例

    #include <cairo.h>
    #include <gtk/gtk.h>
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
        cairo_t *cr;
        cairo_surface_t *surface;
    
        cr = gdk_cairo_create(widget->window);
    
        cairo_set_source_rgb(cr, 0, 0, 0);
    
        surface = cairo_image_surface_create_from_png("omen.png");
        cairo_mask_surface(cr, surface, 0, 0);
        cairo_fill(cr);
    
        cairo_surface_destroy(surface);
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(on_expose_event), NULL);
        g_signal_connect(G_OBJECT(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), 305, 100);
    
        gtk_window_set_title(GTK_WINDOW(window), "mask");
        gtk_widget_set_app_paintable(window, TRUE);
        gtk_widget_show_all(window);
    
        gtk_main();
    
        return 0;
    }

    编译

    gcc -o example-8.o example-8.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序8:平移变换示例

    #include <cairo.h>
    #include <gtk/gtk.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.6, 0.6, 0.6);
        cairo_rectangle(cr, 20, 20, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
    
        cairo_translate(cr, 100, 100);     //通过平移用于空间的原点来修改当前的变换矩阵
    
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 20, 20, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
    
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(window, "expose-event", G_CALLBACK (on_expose_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), 300, 230);
        gtk_widget_set_app_paintable(window, TRUE);
    
        gtk_widget_show_all(window);
    
        gtk_main();
    
        return 0;
    }

    编译

    gcc -o example-9.o example-9.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序9:旋转变换示例

    #include <cairo.h>
    #include <gtk/gtk.h>
    #include <math.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.6, 0.6, 0.6);
        cairo_rectangle(cr, 20, 20, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
    
        cairo_translate(cr, 150, 100);
        cairo_rotate(cr, M_PI/2);   //围绕原点旋转180°
    
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 20, 20, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
    
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(window, "expose-event", G_CALLBACK (on_expose_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), 300, 230);
        gtk_widget_set_app_paintable(window, TRUE);
    
        gtk_widget_show_all(window);
    
        gtk_main();
    
        return 0;
    }

    编译

    gcc -o example-10.o example-10.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序10:缩放变换示例

    #include <cairo.h>
    #include <gtk/gtk.h>
    
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
        cairo_t *cr;
    
        cr = gdk_cairo_create (widget->window);
    
        cairo_save(cr);
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 20, 30, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
        cairo_restore(cr);
    
        cairo_save(cr);
        cairo_translate(cr, 130, 30);
        cairo_scale(cr, 0.7, 0.7);    //对图形进行缩小操作
    
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 0, 0, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
        cairo_restore(cr);
    
        cairo_save(cr);
        cairo_translate(cr, 220, 30);
        cairo_scale(cr, 1.5, 1.5);    //对图形进行放大操作 
    
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 0, 0, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
        cairo_restore(cr);
    
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(window, "expose-event", G_CALLBACK (on_expose_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), 360, 140);
        gtk_widget_set_app_paintable(window, TRUE);
    
        gtk_widget_show_all(window);
    
        gtk_main();
    
        return 0;
    }

    编译

    gcc -o example-11.o example-11.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

    程序11:错切变换示例

    #include <cairo.h>
    #include <gtk/gtk.h>
    
    
    static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
    {
        cairo_t *cr;
        cairo_matrix_t matrix;
    
        cr = gdk_cairo_create (widget->window);
    
        cairo_save(cr);
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 20, 30, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
        cairo_restore(cr);
    
        cairo_save(cr);
        cairo_translate(cr, 130, 30);
        cairo_matrix_init(&matrix,
                          1.0, 0.5,
                          0.0, 1.0,
                          0.0, 0.0);
    
        cairo_transform (cr, &matrix);
    
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 0, 0, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
        cairo_restore(cr);
    
        cairo_save(cr);
        cairo_translate(cr, 220, 30);
        cairo_matrix_init(&matrix,
                          1.0, 0.0,
                          0.7, 1.0,
                          0.0, 0.0);
    
        cairo_transform(cr, &matrix);
    
        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_rectangle(cr, 0, 0, 80, 50);
        cairo_stroke_preserve(cr);
        cairo_set_source_rgb(cr, 1, 1, 1);
        cairo_fill(cr);
        cairo_restore(cr);
    
        cairo_destroy(cr);
    
        return FALSE;
    }
    
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
        g_signal_connect(window, "expose-event", G_CALLBACK(on_expose_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), 360, 140);
        gtk_widget_set_app_paintable(window, TRUE);
    
        gtk_widget_show_all(window);
    
        gtk_main();
    
        return 0;
    }

    编译

    gcc -o example-12.o example-12.c -lcairo -I/usr/include/cairo `pkg-config --cflags --libs gtk+-2.0`

    运行

    image

  • 相关阅读:
    汕头市队赛 SRM1X T1
    夏令营
    路上路径求和
    USACO 刷题记录bzoj
    整除
    Xor路
    超低延时安防直播系统webrtc-client在浏览器播放没有音频的问题如何排查解决?
    如何使用TSINGSEE青犀视频同屏功能组件EasyScreenLive通过sdk推流到腾讯云直播?
    网络穿透/云端组网/视频拉转推服务EasyNTS上云网关运维中数据库检测功能的介绍
    【解决方案】变电站智慧消防如何实现远程集中监控?EasyCVR变电站安全综合管理系统搭建
  • 原文地址:https://www.cnblogs.com/274914765qq/p/4364261.html
Copyright © 2020-2023  润新知