
虛線 (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;
}
#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);
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;
}
#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_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);
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;
}
#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);
cairo_set_line_width (cr, 14);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
cairo_stroke (cr);
繪製了一個線寬為 14px,交合類型為 CAIRO_LINE_JOIN_MITER 的矩形。
沒有留言:
張貼留言