The Cairo graphics tutorial -------Text in Cairo

来源:互联网 发布:基金产品经理 知乎 编辑:程序博客网 时间:2024/05/19 05:33

In this part of the Cairo graphics tutorial, we will work with text.


Soulmate

In the first example, we will display some lyrics on the GTK+ window.

#include <cairo.h>#include <gtk/gtk.h>static gbooleanon_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.1, 0.1);   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_move_to(cr, 20, 60);  cairo_show_text(cr, "They're all good but not the permanent one");  cairo_move_to(cr, 20, 120);  cairo_show_text(cr, "Who doesn't long for someone to hold");  cairo_move_to(cr, 20, 150);  cairo_show_text(cr, "Who knows how to love you without being told");  cairo_move_to(cr, 20, 180);  cairo_show_text(cr, "Somebody tell me why I'm on my own");  cairo_move_to(cr, 20, 210);  cairo_show_text(cr, "If there's a soulmate for everyone");  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), 420, 250);   gtk_window_set_title(GTK_WINDOW(window), "Soulmate");  gtk_widget_set_app_paintable(window, TRUE);  gtk_widget_show_all(window);  gtk_main();  return 0;}

In this example, we display part of the lyrics from the Natasha Bedingfields Soulmate song.

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

Here we select the font face. The function takes three parameters, the font family, font slant and the font weight.

 cairo_set_font_size(cr, 13);

Here we specify the font size.

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

We display the text on the window by specifying the position of the text and calling thecairo_show_text() function.


Soulmate
Figure: Soulmate

Letter by letter

In this effect, we will display a text letter by letter. The letters will be drawn with some delay.

#include <cairo.h>#include <gtk/gtk.h>gpointer text[7] = { "Z", "e", "t", "C", "o", "d", "e" };gboolean timer = TRUE;static gbooleanon_expose_event(GtkWidget *widget,    GdkEventExpose *event,    gpointer data){  cairo_t *cr;  cairo_text_extents_t extents;  static gint count = 0;  cr = gdk_cairo_create(widget->window);  cairo_select_font_face(cr, "Courier",      CAIRO_FONT_SLANT_NORMAL,      CAIRO_FONT_WEIGHT_BOLD);  cairo_set_font_size(cr, 35);  cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);   gint i;  gint x = 0;  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]);    }  count++;  if (count == 8) {      timer = FALSE;      count = 0;  }  cairo_destroy(cr);  return FALSE;}static gbooleantime_handler (GtkWidget *widget){  if (widget->window == NULL) return FALSE;  if (!timer) return FALSE;  gtk_widget_queue_draw(widget);  return TRUE;}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), 300, 90);   gtk_window_set_title(GTK_WINDOW(window), "ZetCode");  gtk_widget_set_app_paintable(window, TRUE);  g_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) window);  gtk_widget_show_all(window);  gtk_main();  return 0;}

In our example, we will draw the "ZetCode" string onto the GTK+ window letter by letter with some delay.

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

We create an array of strings.

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

We select a Courier font face.

 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]);   }

Here we draw the text letter by letter. The extents.width gives us the width of the current letter.


ZetCode
Figure: ZetCode

Puff

In the following example, we create a puff effect. The example will display a growing centered text, that will gradully fade out from some point. This is a very common effect, which you can often see in flash animations.

#include <cairo.h>#include <gtk/gtk.h>gpointer text[7] = { "Z", "e", "t", "C", "o", "d", "e" };gboolean timer = TRUE;static gbooleanon_expose_event(GtkWidget *widget,    GdkEventExpose *event,    gpointer data){  cairo_t *cr;  cairo_text_extents_t extents;  static gdouble alpha = 1.0;  static gdouble size = 1;  gint x = widget->allocation.width / 2;  gint y = widget->allocation.height / 2;  cr = gdk_cairo_create(widget->window);  cairo_set_source_rgb(cr, 0.5, 0, 0);   cairo_paint(cr);  cairo_select_font_face(cr, "Courier",      CAIRO_FONT_SLANT_NORMAL,      CAIRO_FONT_WEIGHT_BOLD);  size += 0.8;  if (size > 20) {      alpha -= 0.01;  }  cairo_set_font_size(cr, size);  cairo_set_source_rgb(cr, 1, 1, 1);   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);  if (alpha <= 0) {      timer = FALSE;  }  cairo_destroy(cr);  return FALSE;}static gbooleantime_handler (GtkWidget *widget){  if (widget->window == NULL) return FALSE;  if (!timer) return FALSE;  gtk_widget_queue_draw(widget);  return TRUE;}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), 350, 200);   gtk_window_set_title(GTK_WINDOW(window), "puff");  gtk_widget_set_app_paintable(window, TRUE);  g_timeout_add(14, (GSourceFunc) time_handler, (gpointer) window);  gtk_widget_show_all(window);  gtk_main();  return 0;}

The example creates a growing and fading text on the GTK+ window.

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

Coordinates of the middle point.

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

We set the background color to dark red color.

 size += 0.8;

Each cycle, the font size will grow by 0.8 units.

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

The fading out begins after the font size is bigger than 20.

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

We get the text metrics.

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

We use the text metrics to center the text on the window.

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

We get the path of the text and set the current clip region to it.

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

We paint the current path with and take alpha value into account.


Puff
Figure: Puff

This chapter covered text in Cairo.



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 消防工程师报考条件二级 二级注册消防工程师报考条件 一级注册消防工程师论坛 二级消防工程师好考吗 一级注册消防工程师招聘 注册消防工程师难考吗 考一级消防工程师有用吗 消防工程师难度 一消防工程师 一级消防工程师考试难度 一级消防工程师好考吗 消防工程师待遇 注册消防工程师一级二级区别 一级注册消防工程师好考吗 注册消防工程师好不好考 一级消防工程师难度 二级注册消防工程师考试科目 二级消防考试时间 一级消防工程师招聘 陕西二级消防工程师报名时间 2017消防工程师考试时间 消防工程师代报名 消防技术综合能力 一级注册消防工程师报考条件 河北二级消防工程师报名时间 二级消防工程师报名条件 消防员考试报考条件 消防技术实务 一级注册消防工程师报名时间 消防安全工程师考试时间 消防注册工程师报考条件 2017一级消防工程师报名时间 二级消防考试科目 辽宁消防工程师报名时间 一级消防工程师免考条件 注册消防工程师考哪几门 注册消防工程师考试题型 湖南消防工程师报名时间 注册消防工程师免考条件 消防注册工程师报名条件 山东消防工程师