Cairo 图形指南 (2) —— 文本

转载 2012年03月29日 17:33:14
本篇讲述如何处理文本。

灵魂伙伴

第一个示例是在 GTK+ 窗口中显示《灵魂伙伴》的部分歌词。

  1. #include <cairo.h>  
  2. #include <gtk/gtk.h>  
  3.    
  4. staticgboolean  
  5. on_expose_event(GtkWidget *widget,  
  6.     GdkEventExpose *event,  
  7.     gpointer data)  
  8. {  
  9.   cairo_t *cr;  
  10.    
  11.   cr = gdk_cairo_create(widget->window);  
  12.    
  13.   cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);  
  14.    
  15.   cairo_select_font_face(cr,"Purisa",  
  16.       CAIRO_FONT_SLANT_NORMAL,  
  17.       CAIRO_FONT_WEIGHT_BOLD);  
  18.    
  19.   cairo_set_font_size(cr, 13);  
  20.    
  21.   cairo_move_to(cr, 20, 30);  
  22.   cairo_show_text(cr,"Most relationships seem so transitory");   
  23.   cairo_move_to(cr, 20, 60);  
  24.   cairo_show_text(cr,"They're all good but not the permanent one");  
  25.    
  26.   cairo_move_to(cr, 20, 120);  
  27.   cairo_show_text(cr,"Who doesn't long for someone to hold");  
  28.    
  29.   cairo_move_to(cr, 20, 150);  
  30.   cairo_show_text(cr,"Who knows how to love you without being told");  
  31.   cairo_move_to(cr, 20, 180);  
  32.   cairo_show_text(cr,"Somebody tell me why I'm on my own");  
  33.   cairo_move_to(cr, 20, 210);  
  34.   cairo_show_text(cr,"If there's a soulmate for everyone");  
  35.    
  36.   cairo_destroy(cr);  
  37.    
  38.   returnFALSE;  
  39. }  
  40.    
  41.    
  42. int main (int argc,char*argv[])  
  43. {  
  44.   GtkWidget *window;  
  45.    
  46.   gtk_init(&argc, &argv);  
  47.    
  48.   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  
  49.    
  50.   g_signal_connect(window,"expose-event",  
  51.       G_CALLBACK(on_expose_event), NULL);  
  52.   g_signal_connect(window,"destroy",  
  53.       G_CALLBACK(gtk_main_quit), NULL);  
  54.    
  55.   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);  
  56.   gtk_window_set_default_size(GTK_WINDOW(window), 420, 250);  
  57.   gtk_window_set_title(GTK_WINDOW(window),"Soulmate");  
  58.   gtk_widget_set_app_paintable(window, TRUE);  
  59.    
  60.   gtk_widget_show_all(window);  
  61.    
  62.   gtk_main();  
  63.    
  64.   return0;  
  65. }  

在这个示例中,显示了 Natasha Bedingfield 的《灵魂伙伴》的部分歌词。(在这里,可以听这首歌,很美妙)

cairo_select_font_face(cr,"Purisa",
   CAIRO_FONT_SLANT_NORMAL,
   CAIRO_FONT_WEIGHT_BOLD);

这里设置字体。这个函数接受了三个字体参数的传入,字体的名称、样式与轻重。


cairo_set_font_size(cr, 13);

这里设定字号。

cairo_move_to(cr, 20, 30);
cairo_show_text(cr,"Most relationships seem so transitory");

 通过在窗口中指定位置并调用 cairo_show_text() 函数显示文本。

 

 

一个字接一个字……

这种效果就是一个字一个字的显示,这些字的绘制存有时间差。


  1. #include <cairo.h>  
  2. #include <gtk/gtk.h>  
  3.    
  4. gpointer text[7] = {"Z","e","t","C","o","d","e"};  
  5. gboolean timer = TRUE;  
  6.    
  7.    
  8. staticgboolean  
  9. on_expose_event(GtkWidget *widget,  
  10.     GdkEventExpose *event,  
  11.     gpointer data)  
  12. {  
  13.   cairo_t *cr;  
  14.   cairo_text_extents_t extents;  
  15.   staticgint count = 0;  
  16.    
  17.   cr = gdk_cairo_create(widget->window);  
  18.    
  19.   cairo_select_font_face(cr,"Courier",  
  20.       CAIRO_FONT_SLANT_NORMAL,  
  21.       CAIRO_FONT_WEIGHT_BOLD);  
  22.    
  23.   cairo_set_font_size(cr, 35);   
  24.   cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);  
  25.    
  26.   gint i;  
  27.   gint x = 0;  
  28.    
  29.   for(i = 0; i < count; i++) {  
  30.       cairo_text_extents(cr, text[i], &extents);  
  31.       x += extents.width + 2;  
  32.       cairo_move_to(cr, x + 30, 50);  
  33.       cairo_show_text(cr, text[i]);   
  34.   }  
  35.    
  36.   count++;  
  37.    
  38.   if(count == 8) {  
  39.       timer = FALSE;  
  40.       count = 0;  
  41.   }  
  42.    
  43.   cairo_destroy(cr);  
  44.    
  45.   returnFALSE;  
  46. }  
  47.    
  48. staticgboolean  
  49. time_handler (GtkWidget *widget)  
  50. {  
  51.   if(widget->window == NULL)returnFALSE;  
  52.    
  53.   if(!timer)returnFALSE;  
  54.    
  55.   gtk_widget_queue_draw(widget);  
  56.   returnTRUE;  
  57. }  
  58.    
  59.    
  60. int main (int argc,char*argv[])  
  61. {  
  62.   GtkWidget *window;  
  63.    
  64.   gtk_init(&argc, &argv);  
  65.    
  66.   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  
  67.    
  68.   g_signal_connect(window,"expose-event",  
  69.       G_CALLBACK(on_expose_event), NULL);  
  70.   g_signal_connect(window,"destroy",  
  71.       G_CALLBACK(gtk_main_quit), NULL);  
  72.    
  73.   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);  
  74.   gtk_window_set_default_size(GTK_WINDOW(window), 300, 90);  
  75.   gtk_window_set_title(GTK_WINDOW(window),"ZetCode");  
  76.   gtk_widget_set_app_paintable(window, TRUE);  
  77.    
  78.   g_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) window);  
  79.    
  80.   gtk_widget_show_all(window);  
  81.    
  82.    
  83.   gtk_main();  
  84.    
  85.   return0;  
  86. }  


在这个示例中,我们在 GTK+ 窗口中画了“ZetCode”这个字串,并让逐个字母伴随一定的时间差逐一显示。


gpointer text[7] = {"Z","e","t","C","o","d","e"};

构造一个字符数组。


cairo_select_font_face(cr,"Courier",
   CAIRO_FONT_SLANT_NORMAL,
   CAIRO_FONT_WEIGHT_BOLD);

将字体设置为 Courier。


for (i = 0; i < count; i++) {
   cairo_text_extents(cr, text[i], &extents);
   x += extents.width + 2;
   cairo_move_to(cr, x + 30, 50);
   cairo_show_text(cr, text[i]); 
}

开始逐个字的绘制。extents.width 给出了当前字符的宽度。

 

膨胀

下面这个示例中,我们制造了一种膨胀的效果。这个示例显示了一串在膨胀的居中文本,并且伴有淡出现象。这是很常见的效果,在 flash 动画里经常见到。


  1. #include <cairo.h>  
  2. #include <gtk/gtk.h>  
  3.    
  4.    
  5. gpointer text[7] = {"Z","e","t","C","o","d","e"};  
  6. gboolean timer = TRUE;  
  7.    
  8.    
  9. staticgboolean  
  10. on_expose_event(GtkWidget *widget,  
  11.     GdkEventExpose *event,  
  12.     gpointer data)  
  13. {  
  14.   cairo_t *cr;  
  15.   cairo_text_extents_t extents;  
  16.    
  17.   staticgdouble alpha = 1.0;  
  18.   staticgdouble size = 1;  
  19.    
  20.    
  21.   gint x = widget->allocation.width / 2;  
  22.   gint y = widget->allocation.height / 2;  
  23.    
  24.   cr = gdk_cairo_create(widget->window);  
  25.    
  26.   cairo_set_source_rgb(cr, 0.5, 0, 0);  
  27.   cairo_paint(cr);  
  28.    
  29.   cairo_select_font_face(cr,"Courier",  
  30.       CAIRO_FONT_SLANT_NORMAL,  
  31.       CAIRO_FONT_WEIGHT_BOLD);  
  32.    
  33.   size += 0.8;  
  34.    
  35.   if(size > 20) {  
  36.       alpha -0.01;  
  37.   }  
  38.    
  39.   cairo_set_font_size(cr, size);  
  40.    
  41.   cairo_set_source_rgb(cr, 1, 1, 1);  
  42.    
  43.   cairo_text_extents(cr,"ZetCode", &extents);  
  44.   cairo_move_to(cr, x - extents.width/2, y);  
  45.   cairo_text_path(cr,"ZetCode");  
  46.   cairo_clip(cr);  
  47.   cairo_stroke(cr);  
  48.   cairo_paint_with_alpha(cr, alpha);  
  49.    
  50.   if(alpha <= 0) {  
  51.       timer = FALSE;  
  52.   }  
  53.    
  54.   cairo_destroy(cr);  
  55.    
  56.   returnFALSE;  
  57. }  
  58.    
  59. staticgboolean  
  60. time_handler (GtkWidget *widget)  
  61. {  
  62.   if(widget->window == NULL)returnFALSE;  
  63.    
  64.   if(!timer)returnFALSE;  
  65.    
  66.   gtk_widget_queue_draw(widget);  
  67.    
  68.   returnTRUE;  
  69. }  
  70.    
  71.    
  72. int main (int argc,char*argv[])  
  73. {  
  74.   GtkWidget *window;  
  75.    
  76.   gtk_init(&argc, &argv);  
  77.    
  78.   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  
  79.    
  80.   g_signal_connect(window,"expose-event",  
  81.       G_CALLBACK(on_expose_event), NULL);  
  82.   g_signal_connect(window,"destroy",  
  83.       G_CALLBACK(gtk_main_quit), NULL);  
  84.    
  85.   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);  
  86.   gtk_window_set_default_size(GTK_WINDOW(window), 350, 200);  
  87.   gtk_window_set_title(GTK_WINDOW(window),"puff");  
  88.   gtk_widget_set_app_paintable(window, TRUE);  
  89.    
  90.   g_timeout_add(14, (GSourceFunc) time_handler, (gpointer) window);  
  91.    
  92.   gtk_widget_show_all(window);  
  93.    
  94.   gtk_main();  
  95.    
  96.   return0;  
  97. }  


这个示例在 GTK+ 窗口中制造了一种膨胀并且淡出的文本渲染效果。


gint x = widget->allocation.width / 2;
gint y = widget->allocation.height / 2;

获取窗口中心坐标。


cairo_set_source_rgb(cr, 0.5, 0, 0);
cairo_paint(cr);

将背景设为暗红色。


size += 0.8;

每轮循环,字号都增长 0.8 个单位。


if (size > 20) {
    alpha -= 0.01;
}

当字号大于 20 的时候,就开始淡出。


cairo_text_extents(cr,"ZetCode", &extents);

获取文本尺寸。


cairo_move_to(cr, x - extents.width/2, y);

根据文本尺寸来将文本定位在窗口的中心位置。


cairo_text_path(cr,"ZetCode");
cairo_clip(cr);

获取文本的的路径,并将其设为当前的裁剪域。


cairo_stroke(cr);
cairo_paint_with_alpha(cr, alpha);

绘制当前的路径,并为之添加 alpha 值(可实现淡出效果)。


转自    http://blog.csdn.net/haiwil/article/details/6771755


相关文章推荐

Cairo 图形指南 (6) —— 透明

这一篇讲述有关透明的一些基本知识,并提供两个有趣的透明效果。 透明是透过某种材质的可见度。理解透明最简单的方式就是想像一下玻璃或者水。从技术上讲,光线可以穿过玻璃,因此我们可以看到玻璃之后的物体...

Cairo 图形指南 (3) —— 变换

这一篇讲述变换(Transformation) 仿射变换是由一些线性变换与平移构成的。线性变换可以写为单个矩阵的形式。旋转是让一个刚体绕一点运动的变换。缩放变换是让物体的形状扩大与减小,并且在各个方向...

Cairo 图形指南 (5) —— 形状与填充

这一部分,讲述一些基本的以及较为高级的形状绘制及其纯色 (solid color)、图案 (pattern) 与渐变 (gradient) 填充方法。 基本形状 Cairo 提供了几个用于...

Cairo 图形指南 (5) —— 图像

在这一篇里,要讲述图像的处理。先是演示如何在 GTK+ 窗口中显示一幅图像,然后再制造一些特效。 图像的显示 在第一个例子里,显示了一幅图像。 [html] view...

Cairo 图形指南 (7) —— 合成

合成 (Compositing) 可以将一些单独的源 (source) 所生成可视元素组合成到单幅图像中去,主要用于创建所有的可视元素作为同一场景的一部分这样一种假象。合成在电影工业中被广为使用,用于...

Cairo 图形指南(1) —— 基本绘图

这一部分讲述如何绘制一些简单的图元,包括直线、填充与笔画操作、虚线、线端(Cap)与线的交合等图形的绘制方法。 直线段 直线段是非常基础的矢量图形对象。画一条直线段,需要调用两个函数:cairo_...
  • haiwil
  • haiwil
  • 2011年09月13日 16:50
  • 4651

Cairo 图形指南 (6) —— 透明

这一篇讲述有关透明的一些基本知识,并提供两个有趣的透明效果。 透明是透过某种材质的可见度。理解透明最简单的方式就是想像一下玻璃或者水。从技术上讲,光线可以穿过玻璃,因此我们可以看到玻璃之后的物体。 ...

Cairo 图形指南 (5) —— 图像

在这一篇里,要讲述图像的处理。先是演示如何在 GTK+ 窗口中显示一幅图像,然后再制造一些特效。 图像的显示 在第一个例子里,显示了一幅图像。 #include #include...
  • haiwil
  • haiwil
  • 2011年09月13日 17:04
  • 1727

GNOME 平台的2D图形编程(GTK,GDK,Cairo...) 简介 [转]

1、用到的库主要是 GDK的函数库  http://library.gnome.org/devel/gdk/stable/ 和 cairo库  http://cairographics...

2.Cairo图形库-定义

The Cairo graphics tutorial 在Cairo图形库指南的这一部分,我们会介绍Cairo图形库里面的一些有用的概念。它们可以帮助我们理解Cario的绘制模式。 上下文图形环境...
  • fo1_sky
  • fo1_sky
  • 2011年04月06日 21:20
  • 2418
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Cairo 图形指南 (2) —— 文本
举报原因:
原因补充:

(最多只允许输入30个字)