2017-04-26 73 views
2

其中,在以下zetcode,開羅上下文cr聲明?cairo上下文對象cr在哪裏聲明?

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

static void do_drawing(cairo_t *); 

struct { 
    int count; 
    double coordx[100]; 
    double coordy[100]; 
} glob; 

static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
    gpointer user_data) 
{ 
    do_drawing(cr); 

    return FALSE; 
} 

static void do_drawing(cairo_t *cr) 
{ 
    cairo_set_source_rgb(cr, 0, 0, 0); 
    cairo_set_line_width(cr, 0.5); 

    int i, j; 
    for (i = 0; i <= glob.count - 1; i++) { 
     for (j = 0; j <= glob.count - 1; j++) { 
      cairo_move_to(cr, glob.coordx[i], glob.coordy[i]); 
      cairo_line_to(cr, glob.coordx[j], glob.coordy[j]); 
     } 
    } 

    glob.count = 0; 
    cairo_stroke(cr);  
} 

static gboolean clicked(GtkWidget *widget, GdkEventButton *event, 
    gpointer user_data) 
{ 
    if (event->button == 1) { 
     glob.coordx[glob.count] = event->x; 
     glob.coordy[glob.count++] = event->y; 
    } 

    if (event->button == 3) { 
     gtk_widget_queue_draw(widget); 
    } 

    return TRUE; 
} 


int main(int argc, char *argv[]) 
{ 
    GtkWidget *window; 
    GtkWidget *darea; 

    glob.count = 0; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 

    darea = gtk_drawing_area_new(); 
    gtk_container_add(GTK_CONTAINER(window), darea); 

    gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK); 

    g_signal_connect(G_OBJECT(darea), "draw", 
     G_CALLBACK(on_draw_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_default_size(GTK_WINDOW(window), 400, 300); 
    gtk_window_set_title(GTK_WINDOW(window), "Lines"); 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 

是開羅方面CR代碼自動聲明,並與DAREA(不幸的名稱繪製區域)相關的,當我們調用函數

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

回答

2

小部件將發出信號並傳遞它的內部cairo上下文。當您連接一個回調來處理信號時,小部件發送cairo上下文,您會收到並處理它。

繪製信號屬於基於GTK Widget類:

gboolean user_function (GtkWidget *widget, CairoContext *cr, gpointer user_data) 

draw documentation:假設窗口小部件時呈現本身

這個信號被髮射。 小部件的左上角必須繪製在上下文中通過的 的原點,並且要根據由 gtk_widget_get_allocated_width()和 gtk_widget_get_allocated_height()返回的值進行調整。

連接到此信號的信號處理程序可以修改cairo上下文 以任何他們喜歡的方式傳遞,並且不需要恢復它。在調用處理程序之後, 信號發射會在調用cairo_save()之前調用cairo_restore()和 。

信號處理程序將獲得一個剪輯區域已經設置爲 小部件的髒區域,即到需要重繪的區域。想要完全避免 重繪自己可以得到截取區域的完整程度與 gdk_cairo_get_clip_rectangle(),或者他們可以得到髒區的細粒度 表示與 cairo_copy_clip_rectangle_list 複雜的小部件()。

+0

謝謝!任何小部件是否允許單個繪圖上下文? – PintoDoido

+2

小工具只能在給定的Cairo上下文中繪製。您可以隨時創建任何其他開羅表面,但是如果您希望將其顯示在屏幕上,則需要將其與GTK +爲您提供的Cairo上下文一起使用。正如ebassi說的那樣, – ebassi

+1

。小部件暴露他們的內部cairo背景。您可以創建其他人,但他們不會顯示在窗口小部件上,要做到這一點,您必須使用暴露的窗口小部件內部cairo上下文。 –