2011年2月4日 星期五

OpenGL text rendering: 利用 Pango Cairo

在 OpenGL 中描繪字串有很多種方法,這裡介紹的方法是利用 Pango 的 Cairo backend 來產生 pixmap ,再將資料送給 OpenGL 當作 texture 輸出。雖然 Cairo 本身也提供很棒的文字輸出服務,但是 Pango 在 Cairo 之上再加上了 markup language,使得字型繪製更有彈性。

以下是我寫的一支小小的 demo 程式,它簡單地展示用 Pango 畫出一個混合粗體與變色的字串。

程式碼片段:
cairo_t* cr = NULL;
cairo_surface_t* surface =NULL;

char string[] = "Pangoのことが<span color='red'><b>大好</b></span>きです";
unsigned char* data = NULL;
PangoLayout *layout;
PangoFontDescription *desc;
int w,h;

surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
cr = cairo_create(surface);

layout = pango_cairo_create_layout (cr);
pango_layout_set_markup(layout, string, -1);
desc = pango_font_description_from_string ("Droid Sans Japanese");
pango_font_description_set_size(desc, PANGO_SCALE * 24);
//pango_layout_set_width(layout, 256*PANGO_SCALE);
//pango_layout_set_wrap(layout, 1);
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);

cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);

pango_layout_get_size(layout, &w, &h);
printf("w:%d, h:%d \n", PANGO_PIXELS(w), PANGO_PIXELS(h));

pango_cairo_show_layout (cr, layout);
data = cairo_image_surface_get_data(surface);
g_object_unref(layout);

glEnable(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

cairo_destroy(cr);
cairo_surface_destroy(surface);


輸出結果:


程式碼下載: pango.tar.bz2