• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 16,  comments - 81,  trackbacks - 0
             
            這一部分講述如何繪制一些簡單的圖元,包括直線、填充與筆畫操作、虛線、線端(Cap)與線的交合等圖形的繪制方法。
            直線段
            直線段是非常基礎的矢量圖形對象。畫一條直線段,需要調用兩個函數:cairo_move_to() 函數,用于設置線段起點;cairo_line_to() 用于設定線段終點。
            #include
            #include
            double coordx[100];
            double coordy[100];
            int count = 0;
            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, 0.5);
                    
                    int i, j;
                    for ( i = 0; i 1; i++ ) {
                            for ( j  = 0; j -1; j++ ) {
                                    cairo_move_to(cr, coordx, coordy);
                                    cairo_line_to(cr, coordx[j], coordy[j]);
                            }
                    }
                    
                    count = 0;
                    cairo_stroke(cr);
                    cairo_destroy(cr);
                    
                    return FALSE;
            }
            gboolean clicked(GtkWidget *widget, GdkEventButton *event,
                             gpointer user_data)
            {
                    if (event->button == 1) {
                            coordx[count] = event->x;
                            coordy[count++] = event->y;
                    }
                    
                    if (event->button == 3) {
                            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);
                    
                    gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK);
                    
                    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(window, "button-press-event",
                                     G_CALLBACK(clicked), NULL);
                    
                    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
                    gtk_window_set_title(GTK_WINDOW(window), "lines");
                    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;
            }
            該示例會創建一個支持鼠標交互繪制直線段的 GTK+ 窗口。在窗口中使用鼠標左鍵隨便點幾下,每一次點擊時,光標位置的坐標都會被記入長度為 100 的數組;然后點擊鼠標右鍵,所有由鼠標左鍵點擊所得到的點會被彼此連接形成直線段;在窗口中再次點擊鼠標右鍵時,會對窗口繪圖區域進行清除。
            下面對該示例程序代碼進行分析:
                    cairo_set_source_rgb(cr, 0, 0, 0);
                    cairo_set_line_width (cr, 0.5);
            設置顏色為黑色,線寬為 0.5pt 為參數,繪制直線段。
                    int i, j;
                    for ( i = 0; i 1; i++ ) {
                            for ( j  = 0; j -1; j++ ) {
                                    cairo_move_to(cr, coordx, coordy);
                                    cairo_line_to(cr, coordx[j], coordy[j]);
                            }
                    }
            用 cairo_move_to() 和 cairo_line_to() 函數在 cr 中定義繪圖路徑 (path),連接 coordx[] 和 coordy[] 所記錄的每個點。
                    cairo_stroke(cr);
            cairo_stroke() 函數會將 cr 中的路徑繪制出來。
                    g_signal_connect(window, "button-press-event",
                                     G_CALLBACK(clicked), NULL);
            設定 button-press-event 事件的回調函數為 clicked ()。
                    if (event->button == 1) {
                            coordx[count] = event->x;
                            coordy[count++] = event->y;
                    }
            在 clicked () 函數中,當鼠標左鍵點擊事件發生時,講光標所在位置的 x 和 y 坐標分別記入數組 coordx 和 coordy。
                    if (event->button == 3) {
                            gtk_widget_queue_draw(widget);
                    }
            在 clicked () 函數中,當鼠標右鍵單擊時,調用 gtk_widget_queue_draw () 函數重繪窗口區域。

            描繪 (Stroke) 與填充 (Fill)
            描繪 (Stroke) 可以繪制形狀的輪廓,填充 (Fill) 則用于向形狀內部灌注顏色。
            #include
            #include
            #include
            static gboolean
            on_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_line_width (cr, 9);
                    cairo_set_source_rgb (cr, 0.69, 0.19, 0);
                    cairo_arc (cr, width / 2, height / 2,
                               (width ) / 2 - 10, 0,
                               2 * M_PI);
                    cairo_stroke_preserve (cr);
                    cairo_set_source_rgb (cr, 0.3, 0.4, 0.6);
                    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 (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), 200, 150);
                    gtk_widget_set_app_paintable (window, TRUE);
                    gtk_widget_show_all (window);
                    gtk_main ();
                    return 0;
            }
            這個示例繪制一個內部填充灰色的圓。
            下面對代碼進行解析:
            #include
            之所以引入這個頭文件,是因為程序中使用了圓周率常量 M_PI。
                    int width, height;
                    gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
            獲取窗口的寬度與高度尺寸。程序中將使用這些值作為繪制圓形的參考尺寸,以實現窗口尺寸變化時,所繪制的圓的尺寸也會相應變化。
                    cairo_set_source_rgb (cr, 0.69, 0.19, 0);
                    cairo_arc (cr, width / 2, height / 2,
                               (width ) / 2 - 10, 0,
                               2 * M_PI);
                    cairo_stroke_preserve (cr);
            描繪圓的輪廓。這里要注意一下 cairo_stroke_preserve () 函數與 cairo_stroke () 函數的區別(最好的辦法是用后者替換一下前者,看看程序執行效果)。cairo_stroke_preserve () 函數會將它繪制的路徑依然保存在 cairo 環境中,而 cairo_stroke () 所繪制的路徑,在繪制完成后,就從 cairo的環境中清除了。
                    cairo_set_source_rgb (cr, 0.3, 0.4, 0.6);
                    cairo_fill (cr);
            對使用 cairo_stroke_preserve () 函數繪制的路徑進行藍色填充。

            虛線 (Dash)
            每條線都可以用不同的虛線筆 (dash pen) 來畫。虛線模式是通過 cairo_set_dash () 函數來設定。模式類型通過一個數組來定義,數組中的值均為正數,它們用于設置虛線的虛部分與實部分。數組的長度與偏移量可以在程序中設定。如果數組的長度 為 0,虛線模式就是被禁止了,那所繪制的線是實線。如果數組長度為 1,則對應著虛實均勻分布的虛線模式。偏移量是用來設置在虛線的始端在一個虛線周期(包含一個實部單元和一個虛部單元)內的起始位置。
            #include
            #include
            static gboolean
            on_expose_event (GtkWidget * widget,
                             GdkEventExpose * event, gpointer data)
            {
                    cairo_t *cr;
                    cr = gdk_cairo_create (widget->window);
                    cairo_set_source_rgba (cr, 0, 0, 0, 1);
                    static const double dashed1[] = { 4.0, 1.0 };
                    static int len1 = sizeof (dashed1) / sizeof (dashed1[0]);
                    static const double dashed2[] = { 4.0, 10.0, 4.0 };
                    static int len2 = sizeof (dashed2) / sizeof (dashed2[0]);
                    static const double dashed3[] = { 1.0 };
                    cairo_set_line_width (cr, 1.5);
                    cairo_set_dash (cr, dashed1, len1, 0);
                    cairo_move_to (cr, 40, 60);
                    cairo_line_to (cr, 360, 60);
                    cairo_stroke (cr);
                    cairo_set_dash (cr, dashed2, len2, 10);
                    cairo_move_to (cr, 40, 120);
                    cairo_line_to (cr, 360, 120);
                    cairo_stroke (cr);
                    cairo_set_dash (cr, dashed3, 1, 0);
                    cairo_move_to (cr, 40, 180);
                    cairo_line_to (cr, 360, 180);
                    cairo_stroke (cr);
                    cairo_destroy (cr);
                    return FALSE;
            }
            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 (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), 400, 300);
                    gtk_widget_show_all (window);
                    gtk_main ();
                    return 0;
            }
            該示例演示了三種虛線模式的設置及繪制。
            下面分析一下關鍵代碼。
                    static const double dashed1[] = { 4.0, 1.0 };
            設定第一條虛線的模式,它的實部是 4 個像素,虛部是 1 個像素。
                    static int len1 = sizeof (dashed1) / sizeof (dashed1[0]);
            計算數組 dashed1 的長度。
                    cairo_set_dash (cr, dashed1, len1, 0);
            設置虛線模式。
                    darea = gtk_drawing_area_new ();
                    gtk_container_add (GTK_CONTAINER (window), darea);
            這次,我們是在 drawing_area 部件上繪圖,不再是窗口區域了。

            線帽 (Line caps)
            線帽是針對直線段的端點形狀而言的,分為三種:

            • CAIRO_LINE_CAP_SQUARE
            • CAIRO_LINE_CAP_ROUND
            • CAIRO_LINE_CAP_BUTT

            對應形狀如下圖所示:

            同一條直線段,CAIRO_LINE_CAP_SQUARE 線帽與 CAIRO_LINE_CAP_BUTT 線帽會導致直線段長度有所差別,前者會比后者長一個線寬尺寸。
            #include
            #include
            static gboolean
            on_expose_event (GtkWidget * widget,
                             GdkEventExpose * event, gpointer data)
            {
                    cairo_t *cr;
                    cr = gdk_cairo_create (widget->window);
                    cairo_set_source_rgba (cr, 0, 0, 0, 1);
                    cairo_set_line_width (cr, 10);
                    cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
                    cairo_move_to (cr, 40, 60);
                    cairo_line_to (cr, 360, 60);
                    cairo_stroke (cr);
                    cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
                    cairo_move_to (cr, 40, 150);
                    cairo_line_to (cr, 360, 150);
                    cairo_stroke (cr);
                    cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
                    cairo_move_to (cr, 40, 240);
                    cairo_line_to (cr, 360, 240);
                    cairo_stroke (cr);
                    cairo_set_line_width (cr, 1.5);
                    cairo_move_to (cr, 40, 40);
                    cairo_line_to (cr, 40, 260);
                    cairo_stroke (cr);
                    cairo_move_to (cr, 360, 40);
                    cairo_line_to (cr, 360, 260);
                    cairo_stroke (cr);
                    cairo_move_to (cr, 365, 40);
                    cairo_line_to (cr, 365, 260);
                    cairo_stroke (cr);
                    cairo_destroy (cr);
                    return FALSE;
            }
            該示例繪制三條具有不同線帽的直線段,同時也展示了不同線帽對線的長度的影響。
            下面對關鍵代碼進行簡單分析:
                    cairo_set_line_width (cr, 10);
            設置線的寬度為 10px。
                    cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
                    cairo_move_to (cr, 40, 150);
                    cairo_line_to (cr, 360, 150);
                    cairo_stroke (cr);
            畫了一條線帽為 CAIRO_LINE_CAP_ROUND 的直線段。
                    cairo_move_to (cr, 40, 40);
                    cairo_line_to (cr, 40, 260);
                    cairo_stroke (cr);
            這是三條豎線之一,用于表現線帽對線的長度的影響。

            線的交合 (Line joins)
            線的交合存在以下三種風格:

            • CAIRO_LINE_JOIN_MITER
            • CAIRO_LINE_JOIN_BEVEL
            • CAIRO_LINE_JOIN_ROUND

            對應形狀如下圖所示。

            #include
            #include
            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.1, 0, 0);
                    cairo_rectangle (cr, 30, 30, 100, 100);
                    cairo_set_line_width (cr, 14);
                    cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
                    cairo_stroke (cr);
                    cairo_rectangle (cr, 160, 30, 100, 100);
                    cairo_set_line_width (cr, 14);
                    cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
                    cairo_stroke (cr);
                    cairo_rectangle (cr, 100, 160, 100, 100);
                    cairo_set_line_width (cr, 14);
                    cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
                    cairo_stroke (cr);
                    cairo_destroy (cr);
                    return FALSE;
            }
            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 (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), 300, 280);
                    gtk_widget_show_all (window);
                    gtk_main ();
                    return 0;
            }

            該示例采用不同的交合類型繪制了三個矩形。
            下面對關鍵代碼進行簡單分析:
                    cairo_rectangle (cr, 30, 30, 100, 100);
                    cairo_set_line_width (cr, 14);
                    cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
                    cairo_stroke (cr);
            繪制了一個線寬為 14px,交合類型為 CAIRO_LINE_JOIN_MITER 的矩形。



            本文來自ChinaUnix博客,如果查看原文請點:
            posted on 2010-04-08 14:15 叫我老王吧 閱讀(1468) 評論(0)  編輯 收藏 引用 所屬分類: GTK
            <2010年4月>
            28293031123
            45678910
            11121314151617
            18192021222324
            2526272829301
            2345678

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久99热国产这有精品| 无码国内精品久久人妻| 久久AⅤ人妻少妇嫩草影院| 久久国产热这里只有精品| 亚洲国产成人精品久久久国产成人一区二区三区综| 久久综合九色综合精品| 欧美国产精品久久高清| 久久久久亚洲AV无码网站| 久久99亚洲综合精品首页| 亚洲国产一成人久久精品| 99久久精品国产一区二区| 久久伊人五月丁香狠狠色| 国产精品久久久久久久久鸭| 欧美午夜A∨大片久久| 国产V综合V亚洲欧美久久| 精品国产乱码久久久久软件| 亚洲午夜精品久久久久久人妖| 国产偷久久久精品专区| 久久久久国产一区二区三区| 久久午夜羞羞影院免费观看| 伊人色综合九久久天天蜜桃| 久久九九亚洲精品| 久久久久国产精品熟女影院 | 亚洲中文字幕伊人久久无码| 久久亚洲私人国产精品vA| 一本色道久久综合| 久久亚洲中文字幕精品一区| 久久久中文字幕| 国产精品美女久久久久| 99久久国产精品免费一区二区| 久久国产成人午夜aⅴ影院| 国产精品久久永久免费| 久久综合给合久久国产免费| 77777亚洲午夜久久多人| 久久久久久免费视频| 四虎国产精品免费久久| 一级做a爰片久久毛片免费陪| 久久久久亚洲AV成人网| 久久久久国产精品麻豆AR影院| 精品国产乱码久久久久久浪潮| 夜夜亚洲天天久久|