last modified July 17, 2023
In this part of the Cairo graphics tutorial we work with text.
In the first example we display some lyrics on the GTK+ window.
static void do_drawing(cairo_t *cr) { 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”); }
In this example, we display part of the lyrics from the Natasha Bedingfield’s 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 the cairo_show_text function.
Figure: Soulmate
Next we show how to center text on the window.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_text_extents_t extents;
GtkWidget *win = gtk_widget_get_toplevel(widget);
gint w, h; gtk_window_get_size(GTK_WINDOW(win), &w, &h);
cairo_select_font_face(cr, “Courier”, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 60);
cairo_text_extents(cr, “ZetCode”, &extents);
cairo_move_to(cr, w/2 - extents.width/2, h/2); cairo_show_text(cr, “ZetCode”); }
The code will center a text on the window. It remains centered, even if we resize the window.
GtkWidget *win = gtk_widget_get_toplevel(widget);
gint w, h; gtk_window_get_size(GTK_WINDOW(win), &w, &h);
To center a text on the window, it is necessary to get the size of of the parent window.
cairo_select_font_face(cr, “Courier”, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 60);
We select a font and its size to be displayed.
cairo_text_extents(cr, “ZetCode”, &extents);
We get the text extents. These are some numbers that describe the text. We need the width of the text for our example.
cairo_move_to(cr, w/2 - extents.width/2, h/2); cairo_show_text(cr, “ZetCode”);
We position the text into the middle of the window and show it using the cairo_show_text method.
Figure: Centered text
Now we show a shaded text on the window.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_select_font_face(cr, “Serif”, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 50);
cairo_set_source_rgb(cr, 0, 0, 0); cairo_move_to(cr, 40, 60); cairo_show_text(cr, “ZetCode”);
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_move_to(cr, 43, 63); cairo_show_text(cr, “ZetCode”); }
To create a shade, we draw the text twice. In different colours. The second text is moved a bit to the right and bottom.
cairo_set_source_rgb(cr, 0, 0, 0); cairo_move_to(cr, 40, 60); cairo_show_text(cr, “ZetCode”);
The first text is drawn in black ink. It serves as a shade.
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_move_to(cr, 43, 63); cairo_show_text(cr, “ZetCode”);
The second text is drawn in some gray ink. It is moved by 3px to the right and to the bottom.
Figure: Shaded text
The following example will create a nice effect. We fill a text with some linear gradient.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_pattern_t *pat;
cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_paint(cr);
gint h = 90;
cairo_select_font_face(cr, “Serif”, CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, h);
pat = cairo_pattern_create_linear(0, 15, 0, h*0.8); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT); cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0); cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
cairo_move_to(cr, 15, 80); cairo_text_path(cr, “ZetCode”); cairo_set_source(cr, pat); cairo_fill(cr); }
We draw a text on the window filled with a linear gradient. The colours are some orange colours.
cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_paint(cr);
To make it more visually appealing, we paint the background in dark gray colour.
pat = cairo_pattern_create_linear(0, 15, 0, h*0.8); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT); cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0); cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
The linear gradient is created.
cairo_move_to(cr, 15, 80); cairo_text_path(cr, “ZetCode”); cairo_set_source(cr, pat); cairo_fill(cr);
The text is displayed on the window. We use the gradient as a source for painting.
Figure: Text filled with gradient
The cairo_show_text method is only suitable for simple text rendering. Cairo developers call it a toy method. More professional text rendering is done with glyphs. A glyph is a graphic symbol which provides a form for a character. A character provides a meaning. It can have multiple glyphs. A character has no intrinsic appearance. A glyph has no intrinsic meaning.
Note that many common programming requirements conserning text are addressed by the Pango library.
static void do_drawing(cairo_t *cr, GtkWidget *widget) { cairo_select_font_face(cr, “Serif”, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 13);
const int n_glyphs = 20 * 35; cairo_glyph_t glyphs[n_glyphs];
gint i = 0; gint x, y;
for (y=0; y<20; y++) { for (x=0; x<35; x++) { glyphs[i] = (cairo_glyph_t) {i, x15 + 20, y18 + 20}; i++; } }
cairo_show_glyphs(cr, glyphs, n_glyphs); }
This code shows 700 glyphs of a chosen font.
const int n_glyphs = 20 * 35; cairo_glyph_t glyphs[n_glyphs];
The glyphs array will store three integer values. The first value is the index of the glyph to the chosen font type. The second and the third values are x, y positions of a glyph.
cairo_show_glyphs(cr, glyphs, n_glyphs);
The cairo_show_glyphs method shows the glyphs on the window.
This chapter covered text in Cairo.