網誌存檔

2010年11月16日 星期二

「轉貼」Cairo 圖形指南 (3) —— Cairo 後端

Cairo 支持多種後端,本文基於幾個示例講述如何使用 Cairo 各種後端創建 PNG 圖像、PDF 文件與 SVG 文件以及如何使用 Cairo 在 GTK 窗口中繪圖。

1. PNG 圖像

第一個示例 (example-1.c) 用於生成 PNG 圖像。

#include

int
main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;

surface =
cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 320, 48);
cr = cairo_create (surface);

cairo_set_source_rgb (cr, 0.627, 0, 0);
cairo_select_font_face (cr, "Adobe Heiti Std",
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_surface_write_to_png (surface, "image.png");

cairo_destroy (cr);
cairo_surface_destroy (surface);

return 0;
}

這個示例是一個很小的控制台程序,運行後可生成一份 PNG 圖像文件。

#include

上述頭文件聲明了上面示例中調用的函數以及一些常量的定義。

cairo_surface_t *surface;
cairo_t *cr;

這兩行代碼聲明了一個 Cairo 外觀與一個 Cairo 環境。

surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 320, 48);
cr = cairo_create(surface);

現在我們生成了 Cairo 外觀與 Cairo 環境,所生成的外觀是一份 320x48 px 的圖像。

cairo_set_source_rgb (cr, 0.627, 0, 0);

設置源的顏色為 darkred,就好比是選擇了暗紅色的顏料。

cairo_select_font_face(cr, "Adobe Heiti Std", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 24.0);

選擇字體類型並設置其尺寸。(註:可使用 "fc-list" 命令查看系統所安裝字體)

cairo_move_to(cr, 10.0, 34.0);
cairo_show_text(cr, "我是中國人,我愛我的祖國。");

將「畫筆」移動到圖像區域的 (10.0, 34.0) 位置開始繪製文本。

cairo_surface_write_to_png(surface, "image.png");

這個函數創建 PNG 圖像。

cairo_destroy(cr);
cairo_surface_destroy(surface);

最後,回收所有 Cairo 環境與外觀所佔用的內存資源。

編譯這個示例:

$ gcc -o example-1 `pkg-config --cflags --libs gtk+-2.0` example-1.c

生成的 PNG 圖像如下圖所示:

2. PDF 文件

在第二個示例 (example-2.c) 中,將使用 Cairo 生成一份 PDF 文件,其內容與第一個示例所生成的圖像是相同的。

#include
#include

int
main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;

surface = cairo_pdf_surface_create ("pdffile.pdf", 320, 48);
cr = cairo_create (surface);

cairo_set_source_rgb (cr, 0.627, 0, 0);
cairo_select_font_face (cr, "Adobe Heiti Std",
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_show_page (cr);

cairo_destroy (cr);
cairo_surface_destroy (surface);

return 0;
}

編譯這個示例:

$ gcc -o example-2 `pkg-config --cflags --libs gtk+-2.0` example-2.c

生成的 PDF 文件,請使用 PDF 閱讀器查看,Linux 用戶可使用 Evince 或 KPDF。

surface = cairo_pdf_surface_create ("pdffile.pdf", 320, 48);

要生成 pdf 文件,必須使用 cairo_pdf_surface () 函數創建一個 pdf 外觀。pdf 文件的頁面大小是以排版標準中的像素點尺寸為單位控制的。

cairo_show_page(cr);

生成的 PDF 文檔在 Evince 中顯示效果如下圖所示:

3. SVG 文件

第三個示例演示如何使用 Cairo SVG 後端生成一份簡單的 SVG (Scalble Vector Graphics) 文件。SVG 技術近幾年很熱門。

#include
#include

int
main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *cr;

surface = cairo_svg_surface_create ("svgfile.svg", 320, 48);
cr = cairo_create (surface);

cairo_set_source_rgb (cr, 0.627, 0, 0);
cairo_select_font_face (cr, "Adobe Heiti Std",
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);
cairo_surface_destroy (surface);

return 0;
}

編譯這個示例:

$ gcc -o example-3 `pkg-config --cflags --libs gtk+-2.0` example-3.c

生成的 SVG 文件可以使用 Firefox、Opera、Inkscape 程序查看。

surface = cairo_svg_surface_create("svgfile.svg", 320, 48);

要生成一份 SVG 文件,必須使用 cairo_svg_surface_create () 函數創建一個 svg 外觀。除此之外,其餘代碼的功用與上述示例類似。

本例生成的 SVG 文件,使用 Firefox 查看結果如下圖所示:

4. GTK 窗口

在最後這個示例中,演示如何在 GTK 窗口中使用 Cairo 繪製圖形。基於 GTK 後端的 Cairo 繪圖模型將貫穿於本指南。

#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.627, 0, 0);
cairo_select_font_face (cr, "Adobe Heiti Std", 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;
}

這個示例程序運行後,會在屏幕中央跳出一個 GTK+ 窗口,上面繪製了一串文本,如下圖所示:

#include
#include

首先要包含 cairo 與 gtk+ 庫的頭文件。

g_signal_connect (window, "expose-event",
G_CALLBACK (on_expose_event), NULL);

當 GTK+窗口被重繪時,會發出 expose-event 信號,我們可將這一信號連接到 on_expose_event () 回調函數上。

gtk_widget_set_app_paintable (window, TRUE);

要在 GTK+ 窗口中繪製 Cairo 圖形,可以使用 GtkDrawingArea widget 或者更為簡單的 GtkWindow widget,本例選擇 GtkWindow 。由 GtkWindow widget 對 expose-event 信號處理後,默認要重新繪製窗口背景,這會將我們在 on_expose_event () 函數中定義的 Cairo 圖形覆蓋掉,因此需要調用 gtk_widget_set_app_paintable () 函數通知 GTK+ 不要這麼幹。如果是在 GtkDrawingArea widget 中繪製 Cairo 圖形,則可省區這一步。

cairo_t *cr;

cr = gdk_cairo_create (widget->window);

Cairo 圖形繪製工作是在 on_expose_event () 函數中進行的,在該函數中,我們為 GTK+ 系統創建了一個 Cairo 環境,並在該環境中繪製了一行文本。

沒有留言:

張貼留言