维护网站建设空间出租,公司做网站需要服务器吗,英文外贸网站,济南制作网站这一部分#xff0c;讲述一些基本的以及较为高级的形状绘制及其纯色 (solid color)、图案 (pattern) 与渐变 (gradient) 填充方法。基本形状Cairo 提供了几个用于绘制基本形状的函数。#include#include#includestatic gbooleanon_expose_event (GtkWidget * widget,GdkEventEx…这一部分讲述一些基本的以及较为高级的形状绘制及其纯色 (solid color)、图案 (pattern) 与渐变 (gradient) 填充方法。基本形状Cairo 提供了几个用于绘制基本形状的函数。#include#include#includestatic gbooleanon_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, 1);cairo_rectangle (cr, 20, 20, 120, 80);cairo_rectangle (cr, 180, 20, 80, 80);cairo_stroke_preserve (cr);cairo_set_source_rgb (cr, 1, 1, 1);cairo_fill (cr);cairo_set_source_rgb (cr, 0, 0, 0);cairo_arc (cr, 330, 60, 40, 0, 2 * M_PI);cairo_stroke_preserve (cr);cairo_set_source_rgb (cr, 1, 1, 1);cairo_fill (cr);cairo_set_source_rgb (cr, 0, 0, 0);cairo_arc (cr, 90, 160, 40, M_PI / 4, M_PI);cairo_close_path (cr);cairo_stroke_preserve (cr);cairo_set_source_rgb (cr, 1, 1, 1);cairo_fill (cr);cairo_set_source_rgb (cr, 0, 0, 0);cairo_translate (cr, 220, 180);cairo_scale (cr, 1, 0.7);cairo_arc (cr, 0, 0, 50, 0, 2 * M_PI);cairo_stroke_preserve (cr);cairo_set_source_rgb (cr, 1, 1, 1);cairo_fill (cr);cairo_destroy (cr);return FALSE;}intmain (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 (darea, 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), 390, 240);gtk_widget_show_all (window);gtk_main ();return 0;}这个示例绘制了矩形、正方形、圆、圆弧和椭圆。下面对关键代码简单分析cairo_rectangle (cr, 20, 20, 120, 80);cairo_rectangle (cr, 180, 20, 80, 80);绘制矩形与正方形。正方形在 cairo 中是矩形的一种特例。cairo_arc (cr, 330, 60, 40, 0, 2 * M_PI);画了一个圆圆心为 (330, 60)px半径为 40px。Cairo 所谓的圆其实是起始角为 0 度终止角为 360 度的弧线。cairo_scale (cr, 1, 0.7);cairo_arc (cr, 0, 0, 50, 0, 2 * M_PI);画椭圆的方法也与画圆类似只是需要先设定长轴与短轴的比例在本例中为 1:0.7。复杂的图形复杂的图形是由简单的图形拼凑出来的譬如下面这个绘制圆角矩形的程序。#include#include#includestatic voiddraw_round_rectangle (cairo_t * cr,double x, double y,double width, double height, double r){cairo_move_to (cr, x r, y);cairo_line_to (cr, x width - r, y);cairo_move_to (cr, x width, y r);cairo_line_to (cr, x width, y height - r);cairo_move_to (cr, x width - r, y height);cairo_line_to (cr, x r, y height);cairo_move_to (cr, x, y height - r);cairo_line_to (cr, x, y r);cairo_arc (cr, x r, y r, r, M_PI, 3 * M_PI / 2.0);cairo_arc (cr, x width - r, y r, r, 3 * M_PI / 2, 2 * M_PI);cairo_arc (cr, x width - r, y height - r, r, 0, M_PI / 2);cairo_arc (cr, x r, y height - r, r, M_PI / 2, M_PI);}static gbooleanon_expose_event (GtkWidget * widget,GdkEventExpose * event, gpointer data){cairo_t *cr;int width, height;double w, h, x, y, r;gtk_window_get_size (GTK_WINDOW (widget), width, height);x width / 5.0;y height / 5.0;w 3 * width / 5.0;h 3 * height / 5.0;r h / 4.0;cr gdk_cairo_create (widget-window);cairo_set_source_rgb (cr, 0.8, 0.4, 0);cairo_set_line_width (cr, 6);draw_round_rectangle (cr, x, y, w, h, r);cairo_stroke_preserve (cr);cairo_set_source_rgb (cr, 0.8, 0.8, 0.2);cairo_fill (cr);cairo_destroy (cr);g_print (test\n);return FALSE;}static gbooleanon_configure_event (GtkWidget * widget,GdkEventConfigure * event, gpointer data){gdk_window_invalidate_rect (widget-window,widget-allocation,FALSE);return FALSE;}intmain (int argc, char *argv[]){GtkWidget *window;GtkWidget *darea;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);g_signal_connect(G_OBJECT(window), configure-event,G_CALLBACK(on_configure_event), NULL);gtk_window_set_position (GTK_WINDOW (window),GTK_WIN_POS_CENTER);gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);gtk_widget_set_app_paintable (window, TRUE);gtk_widget_show_all (window);gtk_main ();return 0;}注因为 The cairo graphics tutorial 在这一部分所提供的示例程序不具代表性因此写了这个程序。该示例程序绘制了一个可跟随窗口尺寸进行缩放变化的圆角矩形。自定义的 draw_round_rectangle () 函数利用 Cairo 提供的基本图元函数利用直线段与圆弧拼凑出圆角矩形。on_configure_event () 函数用于响应窗口尺寸变化事件在其中调用 gdk_window_invalidate_rect () 函数让窗口绘图区域失效并产生窗口重绘制事件(即 expose 事件)。填充 (Fill)虽然上一篇已经讲述了一些有关填充的知识但这里所讲述的内容是与形状相关的。填充可分为三种类型纯色、图案、渐变。纯色 (Solid color)对象的颜色是采用红 (R)、绿 (G)、蓝 (B) 三原色描述的Cairo 的 RGB 取值是从 0 到 1 的双精浮点数。#include#includestatic gbooleanon_expose_event (GtkWidget * widget,GdkEventExpose * event, gpointer data){cairo_t *cr;cr gdk_cairo_create (widget-window);int width, height;gtk_window_get_size (GTK_WINDOW (widget), width, height);cairo_set_source_rgb (cr, 0.5, 0.5, 1);cairo_rectangle (cr, 20, 20, 100, 100);cairo_fill (cr);cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);cairo_rectangle (cr, 150, 20, 100, 100);cairo_fill (cr);cairo_set_source_rgb (cr, 0, 0.3, 0);cairo_rectangle (cr, 20, 140, 100, 100);cairo_fill (cr);cairo_set_source_rgb (cr, 1, 0, 0.5);cairo_rectangle (cr, 150, 140, 100, 100);cairo_fill (cr);cairo_destroy (cr);return FALSE;}intmain (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), 270, 260);gtk_window_set_title (GTK_WINDOW (window), colors);gtk_widget_set_app_paintable (window, TRUE);gtk_widget_show_all (window);gtk_main ();return 0;}该示例绘制了 4 个正方形分别采用四种不同颜色进行填充。这个例子由于很简单就不再像原作者那样自作多情的分析了。图案 (Pattern)所谓图案填充就是将图片填充到形状内部。#include#include#includecairo_surface_t *surface1;cairo_surface_t *surface2;cairo_surface_t *surface3;cairo_surface_t *surface4;static voidcreate_surfaces (){surface1 cairo_image_surface_create_from_png (blueweb.png);surface2 cairo_image_surface_create_from_png (maple.png);surface3 cairo_image_surface_create_from_png (crack.png);surface4 cairo_image_surface_create_from_png (chocolate.png);}static voiddestroy_surfaces (){g_print (destroying surfaces);cairo_surface_destroy (surface1);cairo_surface_destroy (surface2);cairo_surface_destroy (surface3);cairo_surface_destroy (surface4);}static gbooleanon_expose_event (GtkWidget * widget,GdkEventExpose * event, gpointer data){cairo_t *cr;cairo_pattern_t *pattern1;cairo_pattern_t *pattern2;cairo_pattern_t *pattern3;cairo_pattern_t *pattern4;cr gdk_cairo_create (widget-window);int width, height;gtk_window_get_size (GTK_WINDOW (widget), width, height);pattern1 cairo_pattern_create_for_surface (surface1);pattern2 cairo_pattern_create_for_surface (surface2);pattern3 cairo_pattern_create_for_surface (surface3);pattern4 cairo_pattern_create_for_surface (surface4);cairo_set_source (cr, pattern1);cairo_pattern_set_extend (cairo_get_source (cr),CAIRO_EXTEND_REPEAT);cairo_rectangle (cr, 20, 20, 100, 100);cairo_fill (cr);cairo_set_source (cr, pattern2);cairo_pattern_set_extend (cairo_get_source (cr),CAIRO_EXTEND_REPEAT);cairo_arc (cr, 200, 70, 50, 0, 2 * M_PI);cairo_fill (cr);cairo_set_source (cr, pattern3);cairo_pattern_set_extend (cairo_get_source (cr),CAIRO_EXTEND_REPEAT);cairo_rectangle (cr, 20, 140, 100, 100);cairo_fill (cr);cairo_set_source (cr, pattern4);cairo_pattern_set_extend (cairo_get_source (cr),CAIRO_EXTEND_REPEAT);cairo_rectangle (cr, 150, 140, 100, 100);cairo_fill (cr);cairo_pattern_destroy (pattern1);cairo_pattern_destroy (pattern2);cairo_pattern_destroy (pattern3);cairo_pattern_destroy (pattern4);cairo_destroy (cr);return FALSE;}intmain (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);create_surfaces ();gtk_window_set_position (GTK_WINDOW (window),GTK_WIN_POS_CENTER);gtk_window_set_default_size (GTK_WINDOW (window), 270, 260);gtk_window_set_title (GTK_WINDOW (window), patterns);gtk_widget_set_app_paintable (window, TRUE);gtk_widget_show_all (window);gtk_main ();destroy_surfaces ();return 0;}该示例载入 4 张图片分别填充至三个矩形与一个圆形内部区域。所使用的 4 幅图均采用 GIMP 制作。程序中图片的外观 (surface) 实在 on_expose_event () 函数中创建的这并不是很妥当因为窗口每次被重绘时都需要从硬盘中读取图片。pattern1 cairo_pattern_create_for_surface (surface1);由图片外观创建一个图案。cairo_set_source (cr, pattern1);cairo_pattern_set_extend (cairo_get_source (cr),CAIRO_EXTEND_REPEAT);cairo_rectangle (cr, 20, 20, 100, 100);cairo_fill (cr);这里绘制第一个矩形。cairo_set_source () 函数通知 Cairo 环境让它使用一份图案作为源 (source)。图片所形成的图案或许并不适合于形状当使用 cairo_pattern_set_extend () 函数讲图案填充模式设为 CAIRO_EXTEND_REPEAT 时可以让图案像瓦片那样填充于形状内部。cairo_rectangle () 函数创建一个矩形路径cairo_fill () 函数将已经准备好的图案填充到矩形路径所构成的封闭区域中。渐变 (Gradient)在计算机图形学中渐变是形状由明到暗或者从一种颜色向另一种颜色的平滑过度。在 2D 绘图与渲染程序中渐变通常被用于创造多彩的背景与一些特效比如光影的仿真。#include#includestatic gbooleanon_expose_event (GtkWidget * widget,GdkEventExpose * event, gpointer data){cairo_t *cr;cairo_pattern_t *pat1;cairo_pattern_t *pat2;cairo_pattern_t *pat3;cr gdk_cairo_create (widget-window);pat1 cairo_pattern_create_linear (0.0, 0.0, 350.0, 350.0);gdouble j;gint count 1;for (j 0.1; j 1; j 0.1) {if ((count % 2)) {cairo_pattern_add_color_stop_rgb (pat1, j, 0, 0,0);} else {cairo_pattern_add_color_stop_rgb (pat1, j, 1, 0,0);}count;}cairo_rectangle (cr, 20, 20, 300, 100);cairo_set_source (cr, pat1);cairo_fill (cr);pat2 cairo_pattern_create_linear (0.0, 0.0, 350.0, 0.0);gdouble i;count 1;for (i 0.05; i 0.95; i 0.025) {if ((count % 2)) {cairo_pattern_add_color_stop_rgb (pat2, i, 0, 0,0);} else {cairo_pattern_add_color_stop_rgb (pat2, i, 0, 0,1);}count;}cairo_rectangle (cr, 20, 140, 300, 100);cairo_set_source (cr, pat2);cairo_fill (cr);pat3 cairo_pattern_create_linear (20.0, 260.0, 20.0, 360.0);cairo_pattern_add_color_stop_rgb (pat3, 0.1, 0, 0, 0);cairo_pattern_add_color_stop_rgb (pat3, 0.5, 1, 1, 0);cairo_pattern_add_color_stop_rgb (pat3, 0.9, 0, 0, 0);cairo_rectangle (cr, 20, 260, 300, 100);cairo_set_source (cr, pat3);cairo_fill (cr);cairo_pattern_destroy (pat1);cairo_pattern_destroy (pat2);cairo_pattern_destroy (pat3);cairo_destroy (cr);return FALSE;}intmain (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), 340, 390);gtk_window_set_title (GTK_WINDOW (window), gradients);gtk_widget_set_app_paintable (window, TRUE);gtk_widget_show_all (window);gtk_main ();return 0;}在这一示例程序中我们绘制了三个具有不同渐变风格的矩形。pat3 cairo_pattern_create_linear (20.0, 260.0, 20.0, 360.0);这里创建了一个线性渐变图案。参数设定了绘制渐变方向的直线在示例中它是一条竖线。cairo_pattern_add_color_stop_rgb (pat3, 0.1, 0, 0, 0);cairo_pattern_add_color_stop_rgb (pat3, 0.5, 1, 1, 0);cairo_pattern_add_color_stop_rgb (pat3, 0.9, 0, 0, 0);定义了渐变图案的断点。在示例中渐变图案表现为黑色与黄色的过渡。通过添加两个黑色断点和一个黄色断点就可以构成一个水平方向的渐变图案颜色 的变化方向则是沿竖直方向。渐变图案从矩形的上端至下端开始是黑色到 1/10 宽度时黑色便停止了然后就是由黑色向黄色的渐变渲染到达矩形中部时黄色达到饱和状态。黄色断点会在 9/10 宽度处终止最后的 1/10 又是黑色。